*【牛客 1 - A】矩阵(字符串hash)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/84451792

题干:
 

给出一个n * m的矩阵。让你从中发现一个最大的正方形。使得这样子的正方形在矩阵中出现了至少两次。输出最大正方形的边长。

输入描述:

第一行两个整数n, m代表矩阵的长和宽;
接下来n行,每行m个字符(小写字母),表示矩阵;

输出描述:

输出一个整数表示满足条件的最大正方形的边长。

示例1

输入

复制

5 10
ljkfghdfas
isdfjksiye
pgljkijlgp
eyisdafdsi
lnpglkfkjl

输出

复制

3

备注:

对于30%的数据,n,m≤100;
对于100%的数据,n,m≤500;

解题报告:

   非常恶心的字符串Hash,,琢磨了半天才看明白、、这种前缀的是需要去模数的

AC代码:

//#include<cstdio>
//#include<iostream>
//#include<algorithm>
//#include<queue>
//#include<map>
//#include<vector>
//#include<set>
//#include<string>
//#include<cmath>
//#include<cstring>
//using namespace std;
//typedef unsigned long long ull;
//typedef pair<int,int>P;
//#define maxn 505
//int n,m;
//char s[maxn][maxn];
//ull h[maxn][maxn],b[maxn*maxn],base=10007,hhh[maxn][maxn];
//inline int ID(int i,int j) {
//	return (i-1)*m+j;
//}
//inline bool check(int mid) {
//	map<ull,int>M;
//	for(int x=1; x<=n-mid+1; x++)
//		for(int y=1; y<=m-mid+1; y++) {
//			int xx=x+mid-1,yy=y+mid-1;
//			ull val=(h[xx][yy]-h[xx][y-1]-h[x-1][yy]+h[x-1][y-1])*b[(n-x)*m+m-y];
//			if(M.find(val)!=M.end())return 1;
//			M[val]=1;
//		}
//	return 0;
//}
//int main() {
//	scanf("%d%d",&n,&m);
//	for(int i=1; i<=n; i++)scanf("%s",s[i]+1);
//	b[0]=1;
//	for(int i=1; i<=n; i++)
//		for(int j=1; j<=m; j++) {
//			h[i][j]=h[i][j-1]+b[ID(i,j-1)]*(s[i][j]-'a');
//			b[ID(i,j)]=b[ID(i,j-1)]*base;
//		}
////	for(int j=1; j<=m; j++)
////		for(int i=1; i<=n; i++)
////			h[i][j]+=h[i-1][j];
//	int l=0,r=min(n,m),mid,ans=0;
//	while(l<=r) {
//		mid=(l+r)/2;
//		if(check(mid))ans=mid,l=mid+1;
//		else r=mid-1;
//	}
//	printf("%d\n",ans);
//	return 0;
//}




#include<cstdio>
#include<algorithm>
#define N 510
using namespace std;
typedef unsigned long long ll;
const ll D1=97,D2=131;
int n,m,i,j,l,r,mid,ans,t;
char a[N][N];
ll pow1[N],pow2[N],h[N][N],tmp,Hash[N*N];
bool check(int x) {
	for(i=1; i<=n; i++) {
		for(tmp=0,j=1; j<x; j++) tmp=tmp*D1+a[i][j],h[i][j]=0;
		for(j=x; j<=m; j++) h[i][j]=tmp=tmp*D1-pow1[x]*a[i][j-x]+a[i][j];
	}
	for(t=0,i=x; i<=m; i++) {
		for(tmp=0,j=1; j<x; j++) tmp=tmp*D2+h[j][i];
		for(j=x; j<=n; j++) Hash[t++]=tmp=tmp*D2-pow2[x]*h[j-x][i]+h[j][i];
	} 
	sort(Hash,Hash+t);
	for(i=1; i<t; i++) {
		if(Hash[i-1]==Hash[i])return 1;
	}
	return 0;
}
int main() 
{
	scanf("%d%d",&n,&m);
	for(i=1; i<=n; i++) {
		scanf("%s",a[i]+1);
		for(j=1; j<=m; j++) {
			a[i][j]-='a';
		}
	}
	l=1,r=min(n,m);
	pow1[0]=pow2[0]=1;
	for(i=1; i<=n; i++) pow1[i]=pow1[i-1]*D1;
	for(i=1; i<=m; i++) pow2[i]=pow2[i-1]*D2;
	while(l<=r) {
		mid=(l+r)>>1;
		if(check(mid)) l=mid+1,ans=mid;
		else r=mid-1;	
	}

	printf("%d",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/84451792