UVA 11019 字符矩阵哈希

思路:以前没做过字符矩阵的哈希,所以这题是看别人博客写的。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define llson j<<1,l,mid
#define rrson j<<1|1,mid+1,r
#define INF 0x7fffffff
#define seed 13131
#define seed1 1313
#define maxn 1005
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ull p,Hash[maxn][maxn],Hash1[maxn][maxn];
char s[maxn][maxn],str[105][105];
int n,m,x,y;
ull getHash()
{
    ull a,b=0;
    for(int i=0;i<x;i++)
    {
        a=0;
        for(int j=0;j<y;j++)
            a=a*seed1+str[i][j];
        b=b*seed+a;
    }
    return b;
}
int getAns()
{
    ull base,a;
    int ans=0;
    base=1;
    for(int i=0;i<y;i++)
        base*=seed1;
    for(int i=0;i<n;i++)
    {
        a=0;
        for(int j=0;j<y;j++)
            a=a*seed1+s[i][j];
        Hash1[i][y-1]=a;
        for(int j=y;j<m;j++)
            Hash1[i][j]=Hash1[i][j-1]*seed1-s[i][j-y]*base+s[i][j];
    }
    base=1;
    for(int i=0;i<x;i++)
        base*=seed;
    for(int i=y-1;i<m;i++)
    {
        a=0;
        for(int j=0;j<x;j++)
            a=a*seed+Hash1[j][i];
        Hash[x-1][i]=a;
        if(a==p) ans++;
        for(int j=x;j<n;j++)
        {
            Hash[j][i]=Hash[j-1][i]*seed-Hash1[j-x][i]*base+Hash1[j][i];
            if(Hash[j][i]==p) ans++;
        }
    }
    return ans;
}
int main()
{
    //freopen("1.txt","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        scanf("%d%d",&x,&y);
        for(int i=0;i<x;i++)
            scanf("%s",str[i]);
        p=getHash();
        printf("%d\n",getAns());
    }
    return 0;
}
时间: 2024-11-05 04:51:45

UVA 11019 字符矩阵哈希的相关文章

【字符矩阵哈希】【二分答案】【哈希表】bzoj1567 [JSOI2008]Blue Mary的战役地图

引用题解:http://hzwer.com/5153.html 当然,二分可以换成哈希表. #include<cstdio> #include<iostream> #include<cstring> using namespace std; #define MOD 2501 typedef unsigned long long ull; const ull seed1=3659,seed2=1789; ull sum[51][51],sum2[51][51],v[MOD

【字符矩阵哈希】bzoj2351 [BeiJing2011]Matrix

引用题解:http://blog.csdn.net/popoqqq/article/details/41084047 #include<cstdio> #include<cstring> using namespace std; typedef unsigned long long ull; int n,m,a,b,q; const ull seed1=17,seed2=19; #define MOD 1000001 ull v[MOD],sum[1001][1001],ord[2

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(AC自动机)

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

poj 3690 字符矩阵匹配----HASH算法

http://poj.org/problem?id=3690 UVA还有一道也是这样的题,LRJ给的算法是AC自动机----我还没写过,今天用HASH搞了这道题 思路很清晰,但是处理起来还因为HASH函数写混WA了几次... 文本矩阵n*m    T个匹配矩阵p*q 思路: 1.把每一行处理出长为q的hash值 2.对于1中得到的p个哈希值在算一次哈希,这样就把一个矩阵用一个hash值替代了 3.把所有的匹配矩阵压入multiset,然后对于文本矩阵的每一个p*q的子矩阵,算出矩阵哈希值,从mu

uva 1390 - Interconnect(期望+哈希+记忆化)

题目连接:uva 1390 - Interconnect 题目大意:给出n表示有n个点,m表示有m条边,现在任选两点建立一条边,直到整个图联通,问说还需建立边数的期望,建过边的两点仍可以建边. 解题思路:哈希的方法很是巧妙,将各个联通分量中节点的个数c[i]转换成一个30进制的数(因为节点个数最多为30),因为结果很大,所以对1e5+7取模.获得的哈希值作为插入和搜索的起点. #include <cstdio> #include <cstring> #include <alg

字符矩阵的旋转 镜面对称 1.2.2

字符矩阵顺时针旋转90度的时候, 行变成列, 列变成行. 镜面对称不是很难直接上测试代码: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; char mata[100][100], matb[100][100]; int N, M; //N行M列 void rot90(char mata[][100]) { c

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

POJ--2158--------------Milking Grid(最小覆盖字符矩阵)---(开二维kmp)

Milking Grid Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 6169   Accepted: 2573 Description Every morning when they are milked, the Farmer John's cows form a rectangular grid that is R (1 <= R <= 10,000) rows by C (1 <= C <= 75