zoukankan      html  css  js  c++  java
  • [BZOJ 1567] Blue Mary的战役地图

    Link:

    BZOJ 1567 传送门

    Solution:

    矩阵Hash/二维$Hash$模板题

    涉及到需要快速查询、匹配的题目,考虑直接上$Hash$

    矩阵$Hash$其实就是每行先各$Hash$一次,对于$x~x+l-1$行取出$y~y+l-1$列的$Hash$值再进行一次$Hash$即可

    取出$l~r$的$Hash$值的方法:$Hash[j]-Hash[i-1]*base^{j-i+1}$

    注意横竖两次$Hash$乘数要不同!否则碰撞概率极高

    Tip: 判断一个数是否在有序序列中的方式:$*lower\_ bound(begin,end,now)==now$

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef unsigned long long ull;
    const int MAXN=55;
    const ull hsn1=2333333,hsn2=1234567;
    int n,dat[2][MAXN][MAXN];
    ull pre[MAXN],hs[2][MAXN][MAXN],t[MAXN*MAXN];
    
    ull cal(int k,int x,int y,int l)
    {
        ull ret=1;
        for(int i=x;i<=x+l-1;i++)
            ret=ret*hsn2+hs[k][i][y+l-1]-hs[k][i][y-1]*pre[l];
        return ret;
    }
    
    bool check(int x)
    {
        int cnt=0;
        for(int i=1;i<=n-x+1;i++) for(int j=1;j<=n-x+1;j++)
            t[++cnt]=cal(0,i,j,x);
        sort(t+1,t+cnt+1);
        for(int i=1;i<=n-x+1;i++) for(int j=1;j<=n-x+1;j++)
        {
            ull cur=cal(1,i,j,x);
            if(*lower_bound(t+1,t+cnt+1,cur)==cur)
                return true;
        }
        return false;
    }
    
    int main()
    {
        scanf("%d",&n);
        for (int k=0;k<2;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
            scanf("%d",&dat[k][i][j]);
        for(int k=0;k<2;k++)
            for(int i=1;i<=n;i++)
            {
                hs[k][i][0]=1;
                for(int j=1;j<=n;j++) 
                    hs[k][i][j]=hs[k][i][j-1]*hsn1+dat[k][i][j];
            }
        
        pre[0]=1;for(int i=1;i<=50;i++) pre[i]=pre[i-1]*hsn1;
        int l=1,r=n;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid)) l=mid+1;
            else r=mid-1;
        }
        printf("%d",r);
        return 0;
    }
  • 相关阅读:
    数据库是什么以及用来干嘛
    10.3
    10.2
    12.7
    12.5
    12.4
    12.3
    12.2
    12.1JOptionPane
    11.30eclipse常用快捷键
  • 原文地址:https://www.cnblogs.com/newera/p/9232782.html
Copyright © 2011-2022 走看看