「CF1450C1」Errich-Tac-Toe (Easy Version) - 题解

  • 分析

    考虑对矩阵染色

    对于 \(s_{i,j}\) 染色为 \((i+j) \mod 3\)

    显然,不可能存在连续 3 个(不包括斜边)格子同颜色。

    所以只要将同种颜色的格子改为 \(\text{O}\) 就可以直接平局。

    设不为空的格子数量为 \(m\)

    若翻转颜色为 \(0\) 要翻转 \(c_0\) 次,颜色为 \(1\) 要翻转 \(c_1\) 次,颜色为 \(2\) 要翻转 \(c_2\) 次。、

    因为 \(c_0+c_1+c_2=m\)

    \(\min(c_0,c_1,c_2)=\left\lfloor\dfrac{m}{3}\right\rfloor\)

    所以对于本题,对于不为空的格子,选择出现次数最小的颜色所对应的非空格子全部改为 \(\text{O}\) 即可解决本题。

    最后,多测不清空,爆零两行泪 (没错说的就是我这个屑)。


  • 代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int T,n;
char s[305][305],s2[305][305],s3[305][305];
int main()
{	scanf("%d",&T);
	while(T--)
	{	scanf("%d",&n);
		for(int i=1;i<=n;i++)
		{	scanf("%s",s[i]+1);
			for(int j=1;j<=n;j++)
				s2[i][j]=s3[i][j]=s[i][j];
		}
		int m=0,cnt=0,cnt2=0,cnt3=0;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{	if(s[i][j]!='X')continue;
				m++;
				if((i+j)%3==0)cnt++;
				if((i+j)%3==1)cnt2++;
				if((i+j)%3==2)cnt3++;
			}
		int x=min(cnt,min(cnt2,cnt3));
		if(x==cnt)
		{	for(int i=1;i<=n;i++)
			{	for(int j=1;j<=n;j++)
				{	if(s[i][j]!='X')printf(".");
					else if((i+j)%3==0)printf("O");
					else printf("X");
				}
				printf("\n");
			} 
		}
		else if(x==cnt2){
			for(int i=1;i<=n;i++)
			{	for(int j=1;j<=n;j++)
				{	if(s[i][j]!='X')printf(".");
					else if((i+j)%3==1)printf("O");
					else printf("X");
				}
				printf("\n");
			} 
		}
		else if(x==cnt3){
			for(int i=1;i<=n;i++)
			{	for(int j=1;j<=n;j++)
				{	if(s[i][j]!='X')printf(".");
					else if((i+j)%3==2)printf("O");
					else printf("X");
				}
				printf("\n");
			} 
		}
	}
	return 0;
}

\[\text{by Rainy7} \]

posted @ 2020-12-08 19:45  Rainy7  阅读(167)  评论(0编辑  收藏  举报