• 洛谷2177(二维hash)


    考虑这是一个0 1矩阵 我们对每一行进行 hash ,再对每一列进行 hash ,取两个不同的 base ,这样可以一定程度上保证 hash 的正确性,由于蒟蒻我比较菜,没有写散列表,只能 RP++RP++ 看有没有重复了,横行 d[i][j]=d[i][j-1]base1+a[i][j]d[i][j]=d[i][j−1]∗base1+a[i][j] ,再考虑竖列 sum[i][j]=sum[i-1][j]*base2+d[i][j]sum[i][j]=sum[i−1][j]∗base2+d[i][j] ,再将矩阵整个旋转 180°,如果一个子正方形旋转前和旋转后的 hash 值相同,则大概率下,这两个矩阵相同。我们枚举方阵的边长(注意不能二分,这玩意坑了我很久,我二分一直 WA ,仔细一想发现如果前面不满足,后面满足的情况也是存在的,不满足单调性),枚举矩阵的点,进行 hash判断,时间复杂度O(N³),下面贴代码

    //看了看AC记录,貌似 RANK1 ,比 RANK2 快了差不多10倍?其实这题二进制压缩貌似也可做?不过工程量巨大?不管了, QAQ

    // 可能代码略丑,借鉴思路即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef unsigned long long ll;
    ll base1=131,base2=233;
    ll re(){
        char c=getchar();ll all=0,pd=1;
        for(;c>'9'||c<'0';c=getchar()) if(c=='-') pd=-1;
        while(c>='0'&&c<='9') all=all*10+c-'0',c=getchar();return all*pd;
    }const ll N=305;
    char s[N];ll a[N][N],d[N][N],sum[N][N],aa[N][N],sum2[N][N],n,m,qpow1[N],qpow2[N];
    ll cal(ll x,ll y,ll l,ll type){
        if(type==1) return sum[x][y]-sum[x-l][y]*qpow2[l]-sum[x][y-l]*qpow1[l]+sum[x-l][y-l]*qpow1[l]*qpow2[l];
        y=m+l-y,x=n+l-x;
        return sum2[x][y]-sum2[x-l][y]*qpow2[l]-sum2[x][y-l]*qpow1[l]+sum2[x-l][y-l]*qpow1[l]*qpow2[l];
    }
    ll work(ll l){
        for(ll i=l;i<=n;i++)
            for(ll j=l;j<=m;j++)
        if(cal(i,j,l,1)==cal(i,j,l,2)) return 1;
        return 0;
    }ll ans=0;
    int main(){
        n=re(),m=re();
        for(ll i=1;i<=n;i++){
            scanf("%s",s+1);
            for(ll j=1;j<=(ll)strlen(s+1);j++)
                a[i][j]=s[j]-'0';
        }
        qpow1[0]=1;for(int i=1;i<=300;i++) qpow1[i]=qpow1[i-1]*base1;
        qpow2[0]=1;for(int i=1;i<=300;i++) qpow2[i]=qpow2[i-1]*base2;
    
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++)
        d[i][j]=d[i][j-1]*base1+a[i][j];
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++)
        sum[i][j]=sum[i-1][j]*base2+d[i][j];
    
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++)
                aa[i][j]=a[n-i+1][m-j+1];
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++)
        d[i][j]=d[i][j-1]*base1+aa[i][j];
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++)
        sum2[i][j]=sum2[i-1][j]*base2+d[i][j];
    
        for(int i=1;i<=max(n,m);i++)
        if(work(i)) ans=i;
        if(ans!=1&&ans!=0)printf("%llu",ans);
        else printf("-1
    ");
    }
    
  • 相关阅读:
    Node 修改默认镜像源
    Mac下apache虚拟主机配置
    Grep命令出现 Binary file (standard input) matches
    idea取出方法参数提示
    Java8 Optional用法
    Codeforces Round #638 (Div. 2)
    Codeforces Round #637 (Div. 2)
    Codeforces Round #636 (Div. 3)
    Tree
    Educational Codeforces Round 85
  • 原文地址:https://www.cnblogs.com/BLUE-EYE/p/9532946.html
Copyright © 2020-2023  润新知