zoukankan      html  css  js  c++  java
  • AcWing

    题目链接:矩阵

    题意:给定一个$m$行$n$列的$01$矩阵$($只包含数字$0$或$1$的矩阵$)$,再执行$q$次询问,每次询问给出一个$a$行$b$列的$01$矩阵,求该矩阵是否在原矩阵中出现过

    思路:二维哈希,从矩阵的右下角为低位到矩阵的左上角为高位,先求出每一行的一维哈希值$h[i][j]$,在$a$行$b$列的$01$矩阵向下移动的过程中,先向下扩展成$a+1$行$b$列的$01$矩阵,再将最上面的一行减去,这样矩阵就会向下移动一格,设原来$a$行$b$列矩阵的哈希值为$t$,所以新矩阵的哈希值

    $$res=t*p[b]+(h[i+1][j]-h[i+1][j-b]*p[b])-((h[i-a][j]-h[i-a][j-b]*p[b])*p[a*b])$$

    用$set$存储每个子矩阵的哈希值,求出询问矩阵的哈希值,判断是否出现过

    其他二维哈希的题目,令矩阵的右下角为低位、矩阵的左上角为高位,然后推一下公式即可。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <set>
    
    using namespace std;
    
    typedef unsigned long long ull;
    
    const int N = 1010;
    const int M = N * N;
    const ull P = 131;
    
    int n, m, a, b, k;
    ull h[N][N], p[M];
    
    ull Hash(ull f[], int l, int r)
    {
        return f[r] - f[l - 1] * p[r - l + 1];
    }
    
    int main()
    {
        scanf("%d%d%d%d", &n, &m, &a, &b);
        p[0] = 1;
        for (int i = 1; i <= n * m; i++)
            p[i] = p[i - 1] * P;
        for (int i = 1; i <= n; i++) {
            char s[N];
            scanf("%s", s + 1);
            for (int j = 1; j <= m; j++)
                h[i][j] = h[i][j - 1] * P + s[j] - '0';
        }
        set<ull> st;
        for (int i = b; i <= m; i++) {
            ull t = 0;
            int l = i - b + 1, r = i;
            for (int j = 1; j <= n; j++) {
                t = t * p[b] + Hash(h[j], l, r);
                if (j > a) t -= Hash(h[j - a], l, r) * p[a * b];
                if (j >= a) st.insert(t);
            }
        }
        scanf("%d", &k);
        while (k--) {
            ull t = 0;    
            char s[N];
            for (int i = 1; i <= a; i++) {
                scanf("%s", s + 1);
                for (int j = 1; j <= b; j++)
                    t = t * P + s[j] - '0';
            }
            if (st.count(t)) printf("1
    ");
            else printf("0
    ");
        }
        return 0;
    }
  • 相关阅读:
    python之路(三)-深浅拷贝
    Python之路(一)-python简介
    Web端裁剪图片方法
    如何将github上源代码导入eclipse中
    转 GitHub上史上最全的Android开源项目分类汇总
    转 GitHub上最火的40个Android开源项目(二)
    转 GitHub上最火的40个Android开源项目(一)
    转 GitHub上最火的74个Android开源项目(三)
    CSS实现文本溢出的部分用省略号代替的方法
    时尚且健壮: 实现更优秀的CSS
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/12250473.html
Copyright © 2011-2022 走看看