牛客:矩阵 (二维hash + 二分)
原创
©著作权归作者所有:来自51CTO博客作者mb5c5a77ee6227c的原创作品,请联系作者获取转载授权,否则将追究法律责任
矩阵
题解:
这题一看题解就豁然了,首先我们处理出字符串矩阵的hash值,然后二分枚举距离,距离的最大范围是 [1,min(n,m)]
,然后这题数据比较强,好像专门来卡数组取模映射的情况,但是不碍事,我们有 map
,虽然map对于这种 O(n^2)
的时间复杂来说有点慢,但是这题显然没有卡,我用取模时,显然重复几率很大。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
#define ull unsigned long long
#define p 1000007
const ull base1=131;
const ull base2=13331;
ull h[501][501],p1[501],p2[501];
char s[501][501];
map<ull,ull>mp;
ull n,m;
bool check(ull x)
{
mp.clear();
ull ans;
for(ull i=x; i<=n; i++)
{
for(ull j=x; j<=m; j++)
{
ans=h[i][j]-h[i-x][j]*p2[x]-h[i][j-x]*p1[x]+h[i-x][j-x]*p1[x]*p2[x];
mp[ans]++;
if(mp[ans]>1)
{
return true;
}
}
}
return false;
}
ull lower(ull l,ull r)
{
ull ans;
while(l<=r)
{
ull mid=l+r>>1;
if(check(mid))
{
l=mid+1;
ans=mid;
}
else
{
r=mid-1;
}
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for(ull i=1; i<=n; i++)
cin>>s[i]+1;
p1[0]=p2[0]=1;
for(ull i=1; i<=501; i++)
p1[i]=p1[i-1]*base1,p2[i]=p2[i-1]*base2;
for(ull i=1; i<=n; i++)
for(ull j=1; j<=m; j++)
h[i][j]=h[i][j-1]*base1+s[i][j]-'a';
for(ull i=1; i<=n; i++)
for(ull j=1; j<=m; j++)
h[i][j]+=h[i-1][j]*base2;
ull c=min(n,m);
ull ans=lower(1,c);
cout<<ans<<endl;
}