UVA - 11019 Matrix Matcher hash+KMP

题目链接:https://vjudge.net/problem/UVA-11019

题解:

  赶着回寝室

  明天写题解

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
typedef unsigned long long ULL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 2e3+10, M = 1e3+20,inf = 2e9;

const ULL mod = 10000019ULL;
int n,m,x,y,T,fail[N];
char a[N][N],b[N][N];
ULL has[N][N],mp[N][N],s[N],t[N],sqr[N];
void build_fail() {
    int j = 0;
    memset(fail,0,sizeof(fail));
    for(int i = 2; i <= y; ++i) {
        while(j&&s[i]!=s[j+1]) j = fail[j];
        if(s[i] == s[j+1]) j++;
        fail[i] = j;
    }
}
int kmp() {
    int ret = 0, j = 0;
    for(int i = 1; i <= n; ++i) {
        while(j&&s[j+1]!=t[i]) j = fail[j];
        if(s[j+1] == t[i]) j++;
        if(j == x) {
            ret += 1;
            j = fail[j];
        }
    }
    return ret;
}
int main() {
    sqr[0] = 1;
    for(int i = 1; i < N; ++i) sqr[i] = sqr[i-1] * mod;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; ++i) scanf("%s",a[i]+1);
        scanf("%d%d",&x,&y);
        for(int i = 1; i <= x; ++i) scanf("%s",b[i]+1);
        if(n < x || m < y) {
            puts("0");
            continue;
        }
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= m; ++j)
                has[i][j] = has[i][j - 1] * mod + a[i][j];
        }
        for(int i = 1; i <= x; ++i) {
            ULL now = 0, ps = 1;
            for(int j = 1; j <= y; ++j) {
                now = now * mod + b[i][j];
            }
            s[i] = now;
        }
        build_fail();
        int ans = 0;
        for(int j = 1; j <= m - y + 1; ++j) {
            for(int i = 1; i <= n; ++i) {
                int l = j, r = j + y - 1;
                ULL now = has[i][r] - has[i][l-1] * sqr[r - l + 1];
                t[i] = now;
            }
            ans += kmp();
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-12 15:05:19

UVA - 11019 Matrix Matcher hash+KMP的相关文章

UVa 11019 Matrix Matcher - Hash

题目传送门 快速的vjudge传送门 快速的UVa传送门 题目大意 给定两个矩阵S和T,问T在S中出现了多少次. 不会AC自动机做法. 考虑一维的字符串Hash怎么做. 对于一个长度为$l$的字符串$s$,它的Hash值$hash(s) = \sum_{i = 1}^{l}x^{l - i}s_{i}$. 对于二维的情况,我们就取两个基,$x, y$,对于一个$n\times m$的矩阵$A$的Hash值可以表示为 $hash(A) = \sum_{i = 1}^{n}\sum_{j = 1}^

uva 11019 - Matrix Matcher(AC自动机)

题目链接:uva 11019 - Matrix Matcher 题目大意:给出一个n?m的字符矩阵T,要求找出给定r?c的字符矩阵P在T中出现的次数. 解题思路:对P矩阵中的每一行做一个字符串,形成一个字符串集合.构建AC自动机,然后对T矩阵中的每一行进行一次查找,对应出现在该字符串中的子串对应位置+1,如果有一个位置上r次匹配,那么就存在一个匹配矩阵. #include <cstdio> #include <cstring> #include <queue> #inc

UVA 11019 Matrix Matcher 二维的字符串匹配 ac自动机

只要把每行的模版串插到ac自动机,然后匹配行,每次匹配成功,那一行对应的字符矩阵的左上角的计数器+1,最后统计下计数器矩阵有多少个左上角是行数的就可以了. 思路很简单,但想法很好,但要注意模版上有两行是一样的,插入到ac自动机的时候会插到同一个结点上,为了区分,我还是谨慎地开了个vector,然后1A了. #include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,s

uva 11019 Matrix Matcher

题意:给出一个n*m的字符矩阵T,你的任务是找出给定的x*y的字符矩阵P在T中出现了多少次. 思路:要想整个矩阵匹配,至少各行都得匹配.所以先把P的每行看做一个模式串构造出AC自动机,然后在T中的各行逐一匹配,找到P中每一行的所有匹配点. 只要在匹配时做一些附加操作,就可以把匹配出来的单一的行拼成矩形.用一个count[r][c]表示T中一(r,c)为右上角,与P等大的矩形中有多少个 完整的行和P对应位置的行完全相同.当P的第i行出现在T的第r行,起始列编号为c时,意味着count[r-i][c

AC自动机(二维) UVA 11019 Matrix Matcher

题目传送门 题意:训练之南P218 分析:一行一行的插入,一行一行的匹配,当匹配成功时将对应子矩阵的左上角位置cnt[r][c]++;然后统计 cnt[r][c] == x 的数量 #include <bits/stdc++.h> using namespace std; const int N = 1e3 + 5; const int NODE = 1e4 + 5; const int SIZE = 26; char mat1[N][N], mat2[105][105]; int cnt[N

UVA 11019(Matrix Matcher-vector从迭代器中取值,AC自动机匹配字符矩阵)

Problem H Matrix Matcher Input: Standard Input Output: Standard Output Given an N * M matrix, your task is to find the number of occurences of an X * Y pattern. Input The first line contains a single integer t(t ≤ 15), the number of test cases. For e

UVA 11019

Problem HMatrix MatcherInput: Standard Input Output: Standard Output Given an N * M matrix, your task is to find the number of occurences of an X * Y pattern. Input The first line contains a single integer t(t ≤ 15), the number of test cases. For eac

UVA - 10895 Matrix Transpose

UVA - 10895 Matrix Transpose Time Limit:3000MS   Memory Limit:Unknown   64bit IO Format:%lld & %llu [Submit]  [Go Back]  [Status] Description  A: Matrix Transpose  A matrix is a rectangular array of elements, most commonly numbers. A matrix with rows

stack UVA 442 Matrix Chain Multiplication

题目传送门 /* stack 容器的应用:矩阵的表达式求值 A 矩阵是a * b,B 矩阵是b * c,则A * B 是a * c */ #include <cstdio> #include <iostream> #include <algorithm> #include <stack> #include <cmath> #include <cstring> #include <string> using namespac