Newcoder 2 A.矩陣(二分+hash)
阿新 • • 發佈:2018-12-30
Description
給出一個 的矩陣。讓你從中發現一個最大的正方形。使得這樣子的正方形在矩陣中出現了至少兩次。輸出最大正方形的邊長。
Input
第一行兩個整數 代表矩陣的長和寬;
接下來 行,每行 個字元(小寫字母),表示矩陣;
Output
輸出一個整數表示滿足條件的最大正方形的邊長。
Sample Input
5 10
ljkfghdfas
isdfjksiye
pgljkijlgp
eyisdafdsi
lnpglkfkjl
Sample Output
3
Solution
子矩形,二分邊長,若所有該邊長的子矩形 值中有重複則滿足條件
Code
#include<cstdio>
#include<algorithm>
#include<map>
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;
int ID(int i,int j)
{
return (i-1)*m+j;
}
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;
}