.
题意:给出两个正方形矩阵,问两个正方形的最大子正方形的大小。
题解:直接二维哈希搞搞再二分就好了。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[51][51];
unsigned int ha[51][51],base1=137,base2=233,pow1[51],pow2[51];
map<unsigned int,bool>mp[51];
unsigned int get(int x1,int y1,int x2,int y2)
{
return ha[x2][y2]-ha[x1-1][y2]*pow1[x2-x1+1]-ha[x2][y1-1]*pow2[y2-y1+1]+ha[x1-1][y1-1]*pow1[x2-x1+1]*pow2[y2-y1+1];
}
bool chk(int x)
{
for(int i=x;i<=n;i++)
for(int j=x;j<=n;j++)
if(mp[x].count(get(i-x+1,j-x+1,i,j)))
return 1;
return 0;
}
int main()
{
scanf("%d",&n);
pow1[0]=pow2[0]=1;
for(int i=1;i<=n;i++)
{
pow1[i]=pow1[i-1]*base1;
pow2[i]=pow2[i-1]*base2;
}
for(int k=0;k<2;k++)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
memset(ha,0,sizeof(ha));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ha[i][j]=ha[i-1][j]*base1+a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ha[i][j]+=ha[i][j-1]*base2;
/*for(int l=0;l<n;l++)
{
for(int i=l+1;i<=n;i++)
for(int j=l+1;j<=n;j++)
{
printf("%d %d %d %d %u\n",i-l,j-l,i,j,get(i-l,j-l,i,j));
}
}*/
if(k==0)
{
for(int l=0;l<n;l++)
{
for(int i=l+1;i<=n;i++)
for(int j=l+1;j<=n;j++)
{
mp[l+1][get(i-l,j-l,i,j)]=true;
}
}
}
else
{
int l=1,r=n,ans=0;
while(l<=r)
{
int md=l+r>>1;
if(chk(md))
{
ans=md;
l=md+1;
}
else
r=md-1;
}
printf("%d",ans);
}
}
}