CF1660E Matrix and Shifts 题解
\text{Difficulty : 1600}
解题思路:
算是一个比较经典的
第一步操作是棋盘的一个平移。可以将整个棋盘复制三份构成一个
第二步操作需要的次数只需要统计在对角线上的
然后问题就转化为每一个子棋盘上的对角线上有多少
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int T,n,a[4005][4005],cnt,sum[4005][4005],ans;
int SUM(int x,int y){
if(x>2*n||y>2*n)return 0;
if(x<0||y<0)return 0;
return sum[x][y];
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
cnt=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
scanf("%1d",&a[i][j]);
cnt+=a[i][j];
}
for(int i=0;i<2*n;i++)
for(int j=0;j<2*n;j++)
a[i][j]=a[i%n][j%n];
for(int i=0;i<2*n;i++)
for(int j=0;j<2*n;j++)
sum[i][j]=SUM(i-1,j-1)+a[i][j];
ans=2147483647;
for(int i=0;i<n+1;i++)
for(int j=0;j<n+1;j++)
ans=min(ans,n+cnt-2*(SUM(i+n-1,j+n-1)-SUM(i-1,j-1)));
printf("%d\n",ans);
}
return 0;
}