#include<bits/stdc++.h> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define rush ios::sync_with_stdio(false);cin.tie(0); const int inf = 0x3f3f3f3f; const long long linf = 0x3f3f3f3f3f3f3f3f; typedef long long ll; int n; char a[405][405]; int cnt[3]; void solve(){ memset(cnt,0,sizeof(cnt)); cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]+1; } long long num=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(a[i][j]=='X'){ cnt[(i+j)%3]++; } } } int minn=inf; for(int i=0;i<3;i++){ if(cnt[i]<minn){ num=i; minn=cnt[i]; } } // cout<<cnt[0]<<" "<<cnt[1]<<" "<<cnt[2]<<endl; // cout<<num<<endl; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if((i+j)%3==num&&a[i][j]=='X')cout<<'O'; else cout<<a[i][j]; } cout<<endl; } } int main(){ int t; cin>>t; while(t--){ solve(); } }
妙啊。
题意:两种棋,X和O ,3个连续横和三个连续竖都会赢,在k/3 次反转操作内使局面变成平局。
做法:开个cnt数组。cnt[i]存 坐标和%3 与 这个坐标相邻的位置一定存在 cnt[(i+1)%3] 和 cnt[(i+2)%3]中 。因此可以把所有X统计下来,找到cnt[i]最小的i对应的坐标,将其全部替换为O,可以证明,最小的cnt[i]<=(cnt[1]+cnt[2]+cnt[0])/3;