您的位置:首页 > 其它

UVA 11019 Matrix Matcher(字符hash)

2015-08-28 08:32 274 查看
题目:点击打开链接

分析:一个不太科学的方法,复杂度没降多少,将每一行每一列hash出来,然后n^2比较,最坏情况下达10^8

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+7;
const int p=1e6+7;
int t,n,m,x,y;
char str[1010];
int ha[1010][1010];
int he[1010];
LL bin;
void Hash(int id,int l)
{
    LL ans=0;
    for(int i=1;i<=l;i++)
    {
        ans=(ans*1LL*p+str[i])%mod;
        ha[id][i]=ans;
    }
}
void Hash1(int id,int l)
{
    LL ans=0;
    for(int i=1;i<=l;i++)
        ans=(ans*1LL*p+str[i])%mod;
    he[id]=ans;
}
LL Pow(LL a,LL b)
{
    LL ans=1;
    while(b)
    {
        if(b&1)
          ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
bool ok(int i,int j,int k)//i行j列开始
{
    LL res1=(ha[i][j+y-1]-ha[i][j-1]*bin%mod+mod)%mod;
    LL res2=he[k];
    return res1==res2;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        REPF(i,1,n)
        {
            scanf("%s",str+1);
            Hash(i,m);
        }
        scanf("%d%d",&x,&y);
        for(int i=1;i<=x;i++)
        {
            scanf("%s",str+1);
            Hash1(i,y);
        }
        int ans=0;
        bin=Pow(p,y);
        for(int i=1;i<=n;i++)
        {
            if(i+x-1>n) break;
            for(int j=1,k;j<=m;j++)
            {
                if(j+y-1>m) break;
                for(k=i;k<i+x;k++)
                   if(!ok(k,j,k-i+1)) break;
                if(k>=i+x)
                    ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: