牛客练习赛1-A 矩阵
题目
给出一个n * m的矩阵。让你从中发现一个最大的正方形。使得这样子的正方形在矩阵中出现了至少两次。输出最大正方形的边长。
输入描述
第一行两个整数n,m代表矩阵的长和宽;
接下来n行,每行m个字符(小写字母),代表矩阵;
输出描述
输出一个整数表示最大正方形的边长。
分析
显然,这是一个字符串hash的题目;
唯一的难点的就是这个hash方式,get了。
code
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
#define maxn 555
#define mod 100007
struct Edge{
ull v;
int nxt;
}e[maxn*maxn];
int head[mod];
ull base1=1313,base2=13131;
ull hash1[maxn][maxn],hash2[maxn][maxn];
ull bit1[maxn],bit2[maxn];
char s[maxn][maxn];
int n,m,cnt;
void init(){
bit1[0]=bit2[0]=1;
for(int i=1;i<maxn;i++){
bit1[i]=bit1[i-1]*base1;
bit2[i]=bit2[i-1]*base2;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
hash1[i][j]=hash1[i][j-1]*base1+s[i][j];
hash2[i][j]=hash2[i-1][j]*base2+hash1[i][j];
}
}
}
ull cal(int i,int j,int x){
ull ret=hash2[i+x-1][j+x-1];
ret-=hash2[i+x-1][j-1]*bit1[x]+hash2[i-1][j+x-1]*bit2[x];
ret+=hash2[i-1][j-1]*bit1[x]*bit2[x];
return ret;
}
void add(int u,ull v){
e[cnt].v=v;
e[cnt].nxt=head[u];
head[u]=cnt++;
}
bool finds(ull x){
int t=x%mod;
for(int i=head[t];i!=-1;i=e[i].nxt){
if(e[i].v==x) return true;
}
return 0;
}
bool check(int x){
cnt=0;
memset(head,-1,sizeof(head));
for(int i=1;i+x-1<=n;i++){
for(int j=1;j+x-1<=m;j++){
ull t=cal(i,j,x);
if(finds(t)) return true;
add(t%mod,t);
}
}
return 0;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
init();
int l=1,r=min(n,m);
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)) l=mid+1;
else r=mid-1;
}
printf("%d\n",l-1);
return 0;
}
她神采风扬,那双眼眸里仿佛放着万里山河风光!

浙公网安备 33010602011771号