1567: [JSOI2008]Blue Mary的战役地图
二分+哈希
#include<bits/stdc++.h> using namespace std; long long n,a[52][52],b[52][52],tail1,tail2,sum; unsigned long long q1[3000],q2[3000]; bool work(long long p) { tail1=0; for(int i=1;i<=n-p+1;i++) { for(int j=1;j<=n-p+1;j++) { tail1++; q1[tail1]=0; for(int k=1;k<=p;k++) { for(int l=1;l<=p;l++) { q1[tail1]*=13331;q1[tail1]+=a[k+i-1][l+j-1]; } } } } tail2=0; for(int i=1;i<=n-p+1;i++) { for(int j=1;j<=n-p+1;j++) { tail2++; q2[tail2]=0; for(int k=1;k<=p;k++) { for(int l=1;l<=p;l++) { q2[tail2]*=13331;q2[tail2]+=b[k+i-1][l+j-1]; } } } } sort(q1+1,q1+tail2+1); sort(q2+1,q2+tail2+1); sum=tail2;tail1=1;tail2=1; while(tail1<=sum&&tail2<=sum) { if(q1[tail1]==q2[tail2])return true; if(q1[tail1]<q2[tail2])tail1++; else tail2++; } return false; } int main() { scanf("%lld",&n); for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%lld",&a[i][j]); for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%lld",&b[i][j]); long long l=0,r=n,mid; while(l+1<r) { mid=(l+r)/2; if(work(mid))l=mid; else r=mid-1; } if(work(r))printf("%lld\n",r); else printf("%lld\n",l); return 0; }