子正方形
题目链接:子正方形
题目描述
解题思路
我们可以暴力枚举两个矩阵的点作为右下角,然后二分长度,用 h a s h hash hash 判断是否相等。
code
#include<iostream>
#include<cstdio>
using namespace std;
const int p_1=10007ull,p_2=10009ull;
int n,ans;
int a[100][100];
int b[100][100];
int p1[60],p2[60];
bool check(int i,int j,int k,int w,int mid)
{
if(i-mid<0||j-mid<0||w-mid<0||k-mid<0)
return 0;
int aa=a[i][j]-a[i][j-mid]*p1[mid]-a[i-mid][j]*p2[mid]+a[i-mid][j-mid]*p1[mid]*p2[mid];
int bb=b[k][w]-b[k][w-mid]*p1[mid]-b[k-mid][w]*p2[mid]+b[k-mid][w-mid]*p1[mid]*p2[mid];
if(aa==bb)
return 1;
return 0;
}
void ths()
{
p1[0]=p2[0]=1;
for(int i=1;i<=n;i++)
p1[i]=p1[i-1]*p_1,p2[i]=p2[i-1]*p_2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
a[i][j]+=a[i][j-1]*p_1;
b[i][j]+=b[i][j-1]*p_1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
a[i][j]+=a[i-1][j]*p_2;
b[i][j]+=b[i-1][j]*p_2;
}
}
int main()
{
cin>>n;
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]);
ths();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
for(int w=1;w<=n;w++)
{
int l=0,r=n;
while(l<=r)
{
int mid=(l+r)/2;
if(check(i,j,k,w,mid))
l=mid+1,ans=max(ans,mid);
else
r=mid-1;
}
}
cout<<ans<<endl;
}