题目描述
题解
二分答案之后
O(n2)
矩阵hash
就是个裸题
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
#define UL unsigned long long
#define N 55
const UL s=23333333333LL;
const UL S=3115439631056497LL;
int n,ans,a[N][N],b[N][N];
UL mis[N],miS[N],c[N][N],d[N][N];
map <UL,bool> hash;
bool check(int mid)
{
for (int i=1;i<=n;++i)
{
c[i][1]=(UL)a[i][1];
for (int j=2;j<=mid;++j)
c[i][1]=c[i][1]*s+(UL)a[i][j];
for (int j=2;j<=n-mid+1;++j)
c[i][j]=(c[i][j-1]-(UL)a[i][j-1]*mis[mid-1])*s+(UL)a[i][j+mid-1];
}
for (int i=1;i<=n-mid+1;++i)
{
d[1][i]=c[1][i];
for (int j=2;j<=mid;++j)
d[1][i]=d[1][i]*S+c[j][i];
for (int j=2;j<=n-mid+1;++j)
d[j][i]=(d[j-1][i]-c[j-1][i]*miS[mid-1])*S+c[j+mid-1][i];
}
hash.clear();
for (int i=1;i<=n-mid+1;++i)
for (int j=1;j<=n-mid+1;++j)
hash[d[i][j]]=1;
for (int i=1;i<=n;++i)
{
c[i][1]=(UL)b[i][1];
for (int j=2;j<=mid;++j)
c[i][1]=c[i][1]*s+(UL)b[i][j];
for (int j=2;j<=n-mid+1;++j)
c[i][j]=(c[i][j-1]-(UL)b[i][j-1]*mis[mid-1])*s+(UL)b[i][j+mid-1];
}
for (int i=1;i<=n-mid+1;++i)
{
d[1][i]=c[1][i];
for (int j=2;j<=mid;++j)
d[1][i]=d[1][i]*S+c[j][i];
for (int j=2;j<=n-mid+1;++j)
d[j][i]=(d[j-1][i]-c[j-1][i]*miS[mid-1])*S+c[j+mid-1][i];
}
for (int i=1;i<=n-mid+1;++i)
for (int j=1;j<=n-mid+1;++j)
if (hash[d[i][j]]) return 1;
return 0;
}
int find()
{
int l=1,r=n,mid,ans=0;
while (l<=r)
{
mid=(l+r)>>1;
if (check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}
int main()
{
scanf("%d",&n);
mis[0]=1LL;for (int i=1;i<=n;++i) mis[i]=mis[i-1]*s;
miS[0]=1LL;for (int i=1;i<=n;++i) miS[i]=miS[i-1]*S;
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j)
scanf("%d",&a[i][j]);
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j)
scanf("%d",&b[i][j]);
ans=find();
printf("%d\n",ans);
}