引用题解:http://hzwer.com/5153.html
当然,二分可以换成哈希表。
#include<cstdio> #include<iostream> #include<cstring> using namespace std; #define MOD 2501 typedef unsigned long long ull; const ull seed1=3659,seed2=1789; ull sum[51][51],sum2[51][51],v[MOD],pow1[51],pow2[51]; int n,ans,first[MOD],next[MOD],en; void Insert(const ull &V) { int U=(int)(V%MOD); v[en]=V; next[en]=first[U]; first[U]=en++; } bool check(const int &x) { memset(first,-1,sizeof(first)); en=0; for(int i=x;i<=n;i++) for(int j=x;j<=n;j++) Insert(sum[i][j] -sum[i-x][j]*pow1[x] -sum[i][j-x]*pow2[x] +sum[i-x][j-x]*pow1[x]*pow2[x]); for(int i=x;i<=n;i++) for(int j=x;j<=n;j++) { ull t=sum2[i][j] -sum2[i-x][j]*pow1[x] -sum2[i][j-x]*pow2[x] +sum2[i-x][j-x]*pow1[x]*pow2[x]; int o=(int)(t%MOD); for(int i=first[o];i!=-1;i=next[i]) if(t==v[i]) return 1; } return 0; } int main() { scanf("%d",&n); for(int i=1;i<=n;++i)for(int j=1;j<=n;++j) cin>>sum[i][j]; for(int i=1;i<=n;++i)for(int j=1;j<=n;++j) cin>>sum2[i][j]; for(int i=1;i<=n;++i)for(int j=1;j<=n;++j) sum[i][j]+=sum[i-1][j]*seed1; for(int i=1;i<=n;++i)for(int j=1;j<=n;++j) sum[i][j]+=sum[i][j-1]*seed2; for(int i=1;i<=n;++i)for(int j=1;j<=n;++j) sum2[i][j]+=sum2[i-1][j]*seed1; for(int i=1;i<=n;++i)for(int j=1;j<=n;++j) sum2[i][j]+=sum2[i][j-1]*seed2; pow1[0]=pow2[0]=1; for(int i=1;i<=n;i++) pow1[i]=pow1[i-1]*seed1, pow2[i]=pow2[i-1]*seed2; int l=1,r=n; while(l<=r) { int mid=l+r>>1; if(check(mid)) ans=mid,l=mid+1; else r=mid-1; } printf("%d ",ans); return 0; }