题读起来麻烦,实际上就是让你找能不能分成k*k个方块,里面的数字全是0或1
搞一个二维前缀和就可以
注意读入的时候每行要读入固定次数,否则会出错
#include<bits/stdc++.h> using namespace std; char s[2000]; int G[5040][5040]; int sum[5040][5040]; int n; bool judge(int index) { int now=index*index; for(int i=1;i+index-1<=n;i+=index) { for(int j=1;j+index-1<=n;j+=index) { int li=i+index-1; int lj=j+index-1; int ss=sum[li][lj]-sum[i-1][lj]-sum[li][j-1]+sum[i-1][j-1]; if(ss!=0&&ss!=now) return false; } } return true; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",s+1); int num; for(int j=1;j<=n/4;j++)//题目中读入的可能只有一串字符串,所以一定要规定读入次数 { if(s[j]>='A'&&s[j]<='F') num=s[j]-'A'+10; else num=s[j]-'0'; for(int k=(j-1)*4+4;k>=(j-1)*4+1;k--) { G[i][k]=num%2; num/=2; } } } /*for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) printf("%d ",G[i][j]); printf(" "); }*/ for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+G[i][j]; } } int ans=1; for(int i=2;i*i<=n;i++) { if(n%i==0) { if(judge(i)) ans=max(ans,i); if(i*i!=n) { if(judge(n/i)) ans=max(ans,n/i); } } } if(judge(n)) ans=max(ans,n); printf("%d ",ans); }
还可以分行和列考虑,每行每列都统计一遍各个连续子段的长度,取gcd,如果发现有ans是一的话立刻输出结束
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int mp[5205][5205]; char s[5205][5]; int main() { int n; cin>>n; for(int i=0;i<n;i++) { int a; scanf("%s",s[i]); int ss=strlen(s[i]); for(int j=0;j<ss;j++) { if(s[i][j]>='0'&&s[i][j]<='9') a=s[i][j]-'0'; else a=s[i][j]-'A'+10; for(int k=1;k<=4;k++) { mp[i+1][j*4+5-k]=a%2; a/=2; } } } int ans=0; for(int i=1;i<=n&&ans!=1;i++) { int k=1; for(int j=2;j<=n&&ans!=1;j++) { if(mp[i][j]!=mp[i][j-1]) { ans=__gcd(ans,k); k=1; } else k++; } ans=__gcd(ans,k); k=1; for(int j=2;j<=n&&ans!=1;j++) { if(mp[j][i]!=mp[j-1][i]) { ans=__gcd(ans,k); k=1; } else k++; } ans=__gcd(ans,k); } cout<<ans<<endl; return 0; }