CF1450C2 Errich-Tac-Toe (Hard Version)
思路
实际上,如果你会简单版本,那么困难版本也没有那么难了。
同样考虑构造一种通解,如下,
红色的格子改为 X,绿色的格子改为 O,就是一种通解,同样的,这样改可能会超过棋子总数的
同样考虑将棋子按照位置分类,假如该棋子的位置是
显然的是,将所有第 X,所有第 O 是一种方案,还有将第 X,所有第 O 两种方案,总共三种方案,所需要更改的棋子数是将所有棋子全部改完所需要的次数。
根据抽屉原理,三种方案必定至少有一种方案需要的次数少于总棋子数的
AC code
#include<bits/stdc++.h>
using namespace std;
int T,n,numx[3],numo[3],sum,xz;
char ch[305][305];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n),sum=numx[0]=numx[1]=numx[2]=numo[0]=numo[1]=numo[2]=0;
for(int i=1;i<=n;++i)
{
scanf("%s",ch[i]+1);
for(int j=1;j<=n;++j)
{
if(ch[i][j]=='O') ++numo[(i+j)%3],++sum;
if(ch[i][j]=='X') ++numx[(i+j)%3],++sum;//记录每种方案需要更改的棋子数
}
}
if(numx[0]+numo[1]<=sum/3) xz=0;
if(numx[1]+numo[2]<=sum/3) xz=1;
if(numx[2]+numo[0]<=sum/3) xz=2;//判断使用那种方法
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
if(ch[i][j]=='.') printf(".");
else
{
if((i+j)%3!=xz&&(i+j)%3!=(xz+1)%3) printf("%c",ch[i][j]);
else
{
if((i+j)%3==xz) printf("O");
else printf("X");
}//对应更改即可
}
}
puts("");
}
}
return 0;
}