• LA 6893 The Big Painting(矩阵Hash)


    https://vjudge.net/problem/UVALive-6893

    题意:

    给出一个小矩阵和大矩阵,在大矩阵中能找到相同的小矩阵。

    思路:

    矩阵Hash,先对小矩阵计算出它的Hash值,然后处理大矩阵,计算出每个子矩阵的Hash值,然后和小矩阵的Hash值比较是否相等。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<string>
     6 #include<vector>
     7 #include<queue>
     8 #include<cmath>
     9 using namespace std;
    10 
    11 typedef unsigned long long ULL;
    12 
    13 const ULL Base1 = 2007;
    14 const ULL Base2 = 2009;
    15 
    16 int test,n,m,x,y;
    17 ULL ans;
    18 char s[2005][2005],a[2005][2005];
    19 ULL hash;
    20 ULL temp[2005][2005],Temp[2005][2005];
    21 
    22 ULL Gethash()
    23 {
    24     ULL c,sum = 0;
    25     for(int i = 0; i < x; ++i)
    26     {
    27         c = 0;
    28         for(int j = 0; j < y; ++j)
    29         {
    30             c = c*Base1 + a[i][j];
    31         }
    32         sum = sum * Base2 + c;
    33     }
    34     return sum;
    35 }
    36 
    37 //计算出每个子矩阵的Hash值,并比较Hash值是否相等
    38 void GetAns()
    39 {
    40     ULL t=1, c;
    41     for(int i = 0; i < y; ++i) t *= Base1;
    42     for(int i = 0; i < n; ++i)
    43     {
    44         c = 0;
    45         for(int j = 0; j < y; ++j) c = c*Base1 + s[i][j];
    46         temp[i][y-1] = c;
    47         for(int j = y; j < m; ++j)
    48         {
    49             temp[i][j]=temp[i][j-1]*Base1-s[i][j-y]*t+s[i][j];
    50         }
    51     }
    52 
    53     t = 1;
    54     for(int i = 0; i < x; ++i) t *= Base2;
    55     for(int i = y-1; i < m; ++i)
    56     {
    57         c = 0;
    58         for(int j = 0; j < x; ++j) c = c*Base2 + temp[j][i];
    59         Temp[x-1][i] = c;
    60         if(c == hash) ans++;
    61         for(int j = x; j < n; ++j)
    62         {
    63             Temp[j][i] = Temp[j-1][i]*Base2 - temp[j-x][i] * t + temp[j][i];
    64             if(Temp[j][i]== hash) ans++;
    65         }
    66     }
    67 }
    68 
    69 int main()
    70 {
    71     //freopen("D:\input.txt","r",stdin);
    72     while(scanf("%d%d%d%d",&x,&y,&n,&m)!= EOF)
    73     {
    74         for(int i = 0; i < x; ++i) scanf("%s",a[i]);
    75         for(int i = 0; i < n; ++i) scanf("%s",s[i]);
    76         hash = Gethash();
    77         ans = 0;
    78         GetAns();
    79         printf("%llu
    ",ans);
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    求树的直径算法
    二叉排序树BST+求树深度算法
    HDU1114Piggy-Bank(完全背包)
    HDU1102(最小生成树Kruskal算法)
    NYoj289苹果(0-1背包)
    NYOJ201作业题
    C#发送邮件附件
    JS用户登录保存账号密码
    远程连接服务器
    博客园页面更新了
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6845476.html
Copyright © 2020-2023  润新知