The Big Painting(二维字符串hash)

题目链接:https://vjudge.net/problem/Gym-100783J http://codeforces.com/gym/100783

题意:给你一个 a * b 大小的二维字符串,问其在一个 n * m 大小的二维字符串中出现的次数。

思路:二维字符串hash,先一行一行的hash,把每行的hash值再按列进行hash,两次使用的 base 不同。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N = 2010;
const ull base1 = 131;
const ull base2 = 233;

int n, m, p, q;

char s1[N][N];
char s2[N][N];
ull r[N][N];
ull c[N][N];
ull hash1;

int main()
{
    scanf("%d %d %d %d", &n, &m, &p, &q);
    for(int i = 0; i < n; i++)
    {
        getchar();
        ull sum = 0;
        for(int j = 0; j < m; j++)
        {
            scanf("%c", &s1[i][j]);
            sum = sum * base1 + s1[i][j];
        }
        hash1 = hash1 * base2 + sum;
    }
    for(int i = 0; i < p; i++)
    {
        getchar();
        for(int j = 0; j < q; j++) scanf("%c", &s2[i][j]);
    }
    ull now = 1;
    for(int i = 0; i < m; i++) now *= base1;
    for(int i = 0; i < p; i++)
    {
        ull sum = 0;
        for(int j = 0; j < m; j++)
        {
            sum = sum * base1 + s2[i][j];
        }
        r[i][m - 1] = sum;
        for(int j = m; j < q; j++)
        {
            r[i][j] = r[i][j - 1] * base1 + s2[i][j] - s2[i][j - m] * now;
        }
    }
    now = 1;
    int ans = 0;
    for(int i = 0; i < n; i++) now *= base2;
    for(int i = m - 1; i < q; i++)
    {
        ull sum = 0;
        for(int j = 0; j < n; j++)
        {
            sum = sum * base2 + r[j][i];
        }
        c[n - 1][i] = sum;
        if(c[n - 1][i] == hash1)
        {
//            cout << n - 1 << " " << i << endl;
            ans++;
        }
        for(int j = n; j < p; j++)
        {
            c[j][i] = c[j - 1][i] * base2 + r[j][i] - r[j - n][i] * now;
            if(c[j][i] == hash1)
            {
//                cout << j << " " << i << endl;
                ans++;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}
View Code

 

posted @ 2020-05-11 17:21  LightandDust  阅读(173)  评论(0)    收藏  举报