zoukankan      html  css  js  c++  java
  • 【poj3690】Constellations 哈希

    传送门

    题目分析

    考虑将大矩阵的每个1*q矩阵哈希值求出,然后让小矩阵的第一行在大矩阵中找,如果找到,并且能匹配所有行则出现过。否则没出现过。

    在初始化1*q矩阵时可以进行优化:假设该行为123456,要求1*5的矩阵哈希值,可以先暴力求出1~5,为 $1 * H^4 + 2 * H^3 + 3 * H^2 + 4 * H + 5$,现在要删除1添加6:变为$2 * H^4 + 3 * H^3 + 4 * H^2 + 5 * H + 6$,也就是先减去1的哈希值乘以$H^{len - 1}$,然后乘以H,加上6的哈希值。代码如下:

      for(int i = 1; i <= n; i++){
          for(int k = 1; k <= q; k++)
              fixedHash[i][1] = fixedHash[i][1] * H + getVal(matrix[i][k]);
          for(int j = 2; j <= m - q + 1; j++)
              fixedHash[i][j] = (fixedHash[i][j - 1] - getVal(matrix[i][j - 1]) * poww[q - 1]) * H + getVal(matrix[i][j + q - 1]);
      }

     code

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    
    const int N = 1005;
    typedef unsigned long long ull;
    const ull H = 2;
    ull fixedHash[N][N], hash[100], poww[100];
    int n, m, T, p, q, k;
    char matrix[N][N], small[100][100];
    
    inline int getVal(char x){
        return x == '*' ? 1 : 0;
    }
    
    inline bool check(int x, int y){
        for(int k = x + 1; k <= x + p - 1; k++)
            if(fixedHash[k][y] != hash[k - x + 1])
                return false;
        return true;
    }
    
    int main(){
        freopen("h.in", "r", stdin);
        poww[0] = 1;
        for(int i = 1; i <= 100; i++) poww[i] = poww[i - 1] * H;
        while(scanf("%d%d%d%d%d", &n, &m, &T, &p, &q), n + m + T + p + q){
            memset(matrix, 0, sizeof matrix);
            for(int i = 1; i <= n; i++) scanf("%s", matrix[i] + 1);
            memset(fixedHash, 0, sizeof fixedHash);
            for(int i = 1; i <= n; i++){
                for(int k = 1; k <= q; k++)
                    fixedHash[i][1] = fixedHash[i][1] * H + getVal(matrix[i][k]);
                for(int j = 2; j <= m - q + 1; j++)
                    fixedHash[i][j] = (fixedHash[i][j - 1] - getVal(matrix[i][j - 1]) * poww[q - 1]) * H + getVal(matrix[i][j + q - 1]);
            }
            int cnt = 0;
            for(int i = 1; i <= T; i++){
                memset(small, 0, sizeof small);
                for(int j = 1; j <= p; j++)
                    scanf("%s", small[j] + 1);
                memset(hash, 0, sizeof hash);
                for(int j = 1; j <= p; j++)
                    for(int k = 1; k <= q; k++)
                        hash[j] = hash[j] * H + getVal(small[j][k]);
                bool flag = true;
                for(int j = 1; j <= n - p + 1; j++){
                    for(int k = 1; k <= m - q + 1; k++){
                        if(fixedHash[j][k] == hash[1])
                            if(check(j, k)){
                                cnt++;
                                flag = false;
                                break;
                            }
                    }
                    if(!flag) break;
                }
            }
            printf("Case %d: %d
    ", ++k, cnt);
        }
    }
  • 相关阅读:
    java四种数组排序
    hadoop安装及配置
    Talend初试,实现定时同步
    JAVA语言概述和基本语法知识点
    Maven项目资源文件打包错误
    Ajax同步和异步
    Nginx + Tomcat 负载均衡
    PLSQL安装配置
    WebStorm 设置光标位置不随意停靠
    Hello Node.js
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7434867.html
Copyright © 2011-2022 走看看