zoukankan      html  css  js  c++  java
  • 二维hash(Uva 12886)

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=88791(题目连接)

    这道道题就是让你在大矩阵里找小矩阵,用矩阵hash

    用矩阵hash之前我们先定义下面这些玩意

    hash1[][]记录横列的的hash值

    hash2[][]记录纵向的hahs值

    hash表示小矩阵的hash值

    定义两个种子常数

    const ULL seed1=10000007;
    const ULL seed2=100000007;

    两个种子的值不能相同,因为有时横向和纵向的hash值会相同。所以要用不同的种子值,orz= =

    先求小矩阵的的hash值

     1 ULL get_hash()
     2 {
     3      ULL t=0;
     4     for(int i=0;i<x;i++)
     5     {
     6          ULL cnt=0;
     7          for(int j=0;j<y;j++)
     8             cnt=cnt*seed1+s[i][j];//
     9          t=t*seed2+cnt;
    10     }
    11     return t;
    12 }

    然后在大矩阵中构造小矩阵。。。。。想见代码吧= =

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #define maxn 2005
    using namespace std;
    typedef unsigned long long ULL;
    const ULL seed1=10000007;
    const ULL seed2=100000007;
    char s[maxn][maxn];
    char ch[maxn][maxn];
    ULL hash1[maxn][maxn];
    ULL hash2[maxn][maxn];
    ULL hash;
    ULL ans;
    int x,y,n,m;
    ULL get_hash()
    {
         ULL t=0;
        for(int i=0;i<x;i++)
        {
             ULL cnt=0;
             for(int j=0;j<y;j++)
                cnt=cnt*seed1+s[i][j];
             t=t*seed2+cnt;
        }
        return t;
    }
    void count_num()
    {
        ULL c=1;
        for(int i=0;i<y;i++)
        c=c*seed1; //等会求构造矩阵的hash值需要减去第j-y位置的字符的hash值,所以要进行这步。。。
        for(int i=0;i<n;i++)
        {
            ULL cnt=0;
            for(int j=0;j<y;j++)
                cnt=cnt*seed1+ch[i][j];
            hash1[i][y-1]=cnt;
            for(int j=y;j<m;j++)
            {
                hash1[i][j]=hash1[i][j-1]*seed1-ch[i][j-y]*c+ch[i][j];//求横列的hash值
            }
        }
         c=1;
         for(int i=0;i<x;i++)
            c=c*seed2;
         for(int i=y-1;i<m;i++)
         {
             ULL a=0;
             for(int j=0;j<x;j++)
                 a=a*seed2+hash1[j][i];//这里因为将横列的的字符用他的hash值代替= =
             hash2[x-1][i]=a;
             if(a==hash)
                ans++;
             for(int j=x;j<n;j++)
             {
                 hash2[j][i]=hash2[j-1][i]*seed2-hash1[j-x][i]*c+hash1[j][i];
                    if(hash2[j][i]==hash)//相同ans++
                    ans++;
             }
         }
    }
    int main()
    {
        while(scanf("%d %d %d %d",&x,&y,&n,&m)!=EOF)
        {
            getchar();
            memset(hash1,0,sizeof(hash1));
            memset(hash2,0,sizeof(hash2));
            for(int i=0;i<x;i++)
                scanf("%s",s[i]);
            for(int i=0;i<n;i++)
                scanf("%s",ch[i]);  
            hash=get_hash();
            ans=0;
            count_num();
            printf("%llu
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    绿色简洁供应商采购后台管理系统模板——后台
    通用的电子商务商城后台管理界面模板——后台
    透明的企业网站卡通后台模板——后台
    绿色的宠物店cms后台管理系统模板——后台
    蓝色的cms企业记账管理后台模板源码——后台
    简洁的响应式博客后台管理模板——后台
    基于bootstrap物资管理系统后台模板——后台
    黑色的网站后台管理系统ui界面——后台
    蓝色的企业后台cms管理系统——后台
    黑色的cms商城网站后台管理模板——后台
  • 原文地址:https://www.cnblogs.com/NaCl/p/9580181.html
Copyright © 2011-2022 走看看