矩阵hash+二分(慎用map)

来源:互联网 发布:mac 能玩魔兽争霸 编辑:程序博客网 时间:2024/06/07 07:05
时间限制:1秒 空间限制:131072K

题目描述

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

输入描述:

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

输出描述:

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

输入

5 10ljkfghdfasisdfjksiyepgljkijlgpeyisdafdsilnpglkfkjl

输出

3

备注:

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

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

这个和一维的差不多,坑点还是那个坑点,慎用map

代码:

#include<bits/stdc++.h>using namespace std;typedef unsigned long long ull;const int maxn=600;int n,m;char a[maxn][maxn];ull hashh[maxn][maxn],tmp[maxn][maxn];inline void compute(int k){    const ull B1=9973;    const ull B2=100000007;    ull t1=1;    for(int j=0; j<k; j++)        t1*=B1;    for(int i=0; i<n; i++)    {        ull e=0;        for(int j=0; j<k; j++)            e=e*B1+a[i][j];        for(int j=0; j+k<=m; j++)        {            tmp[i][j]=e;            if(j+k<m)                e=e*B1-t1*a[i][j]+a[i][j+k];        }    }    ull t2=1;    for(int i=0; i<k; i++)    {        t2*=B2;    }    for(int j=0; j+k<=m; j++)    {        ull e=0;        for(int i=0; i<k; i++)            e=e*B2+tmp[i][j];        for(int i=0; i+k<=n; i++)        {            hashh[i][j]=e;            if(i+k<n)                e=e*B2-t2*tmp[i][j]+tmp[i+k][j];        }    }}//map<ull,int>MAP;ull node[maxn*maxn];inline int check(int x){    compute(x);    int flag=0;    int k=0;    for(int i=0; i+x<=n; i++)        for(int j=0; j+x<=m; j++)        {            node[k++]=hashh[i][j];        }    sort(node,node+k);    for(int i=1; i<k; i++)    {        if(node[i]==node[i-1])        {            flag=1;            break;        }    }    return flag;}inline int minn(int x,int y){    if(x<y)        return x;    return y;}int main(){    scanf("%d%d",&n,&m);    int r=minn(n,m);    int l=0;    for(int i=0; i<n; i++)    {        scanf("%s",a[i]);    }    while(l<r)    {        int mid=(l+r+1)>>1;        if(check(mid))        {            l=mid;        }        else            r=mid-1;    }    printf("%d\n",l);}

原创粉丝点击