【Ybtoj 第7章例题5】子正方形【哈希】

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


解题思路

这道题矩阵大小才 50 ,我们可以直接用 hash 暴搜。

先枚举两个矩阵所选的矩阵的右下角,然后再二分枚举矩阵大小,取最大值即可。


代码

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ull unsigned long long 

const ull p=131,q=313;
using namespace std;

int n,a[60][60],b[60][60],l,r,mid,ans;
ull hs1[60][60],hs2[60][60];

struct c{
    
    
	ull x,y;
}base[60];

bool check(int mid,int x,int y,int xx,int yy){
    
    
	return ((hs1[x][y]-hs1[x-mid][y]*base[mid].x-hs1[x][y-mid]*base[mid].y+hs1[x-mid][y-mid]*base[mid].x*base[mid].y)==
	(hs2[xx][yy]-hs2[xx-mid][yy]*base[mid].x-hs2[xx][yy-mid]*base[mid].y+hs2[xx-mid][yy-mid]*base[mid].x*base[mid].y));
}

int main(){
    
    
	scanf("%d",&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]);
			
	base[0].x=base[0].y=1ull;
	for(int i=1;i<=n;i++) base[i].x=base[i-1].x*p;
	for(int i=1;i<=n;i++) base[i].y=base[i-1].y*q;
	
	for(int i=1;i<=n;i++)
	{
    
    
		for(int j=1;j<=n;j++)
		{
    
    
			hs1[i][j]=hs1[i-1][j]*p+a[i][j];
			hs2[i][j]=hs2[i-1][j]*p+b[i][j];
		}	
	}
	for(int i=1;i<=n;i++)
	{
    
    
		for(int j=1;j<=n;j++)
		{
    
    
			hs1[i][j]+=hs1[i][j-1]*q;
			hs2[i][j]+=hs2[i][j-1]*q;
		}	
	}
	
	
	for(int sx=1;sx<=n;sx++)
		for(int sy=1;sy<=n;sy++)
			for(int tx=1;tx<=n;tx++)
				for(int ty=1;ty<=n;ty++)
				{
    
    
					l=0,r=min(min(sx,sy),min(tx,ty));
					while(l<=r)
					{
    
    
						mid=(l+r)>>1;
						if(check(mid,sx,sy,tx,ty))
						{
    
    
							ans=max(mid,ans);
							l=mid+1;
						}
						else r=mid-1;
					}
					
				}
	printf("%d",ans);
}


猜你喜欢

转载自blog.csdn.net/kejin2019/article/details/114409086