• UVA 11019 Matrix Matcher(哈希)


    题意

    给定一个 (n imes m) 的矩阵,在给定一个 (x imes y) 的小矩阵,求小矩阵在大矩阵中出现的次数。

    (1 leq n,m leq 1000)

    (1leq x,y leq 100)

    思路

    做法比较显然,先对大矩阵哈希,在每个位上确定一个“位权”,(Base^k) ,对于矩阵的 ((x,y)) 位置,可以令 (k=(x-1)*m+y-1) ,然后求二维前缀和。接下来把小矩阵放在大矩阵的 ((1,1)(x,y)) 位置哈希,将哈希值进行比较。接下来考虑的就是移动矩阵哈希值的变化,不难发现,因为 ((1,1)) 的位权是 (1) ,所以移动到哪里,哈希值就乘上那里的位权即可。

    关于哈希的基数和模数的取值,首先基数 (Base) 要大于不同元素的个数,模数尽量取大质数,最好是孪生的,但注意 (1e9+7,1e9+9) 由于太大众,不免会被卡,我个人习惯再取一个 (19260817) 。然后 (101111,101113,101117,101119) 也是挺好记的质数,在用链式哈希表的时候可以当一维数组下标。

    代码

    #include<bits/stdc++.h>
    #define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
    #define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
    typedef long long LL;
    using namespace std;
    const int Base[3]={29,31,37};
    const int Mod[3]={(int)1e9+7,(int)1e9+9,1926081};
    const int N=1005;
    char A[N][N],B[N][N];
    LL pB[3][N*N];
    LL s[3][N][N],h[3];
    int n,m,p,q;
    inline int Hs(int x,int y){return (x-1)*m+y-1;}
    
    LL S(int k,int X1,int Y1,int X2,int Y2)
    {
    	return	(
    		(s[k][X2][Y2]-s[k][X1-1][Y2]-s[k][X2][Y1-1]+s[k][X1-1][Y1-1])
    		%Mod[k]+Mod[k]
    	)%Mod[k];
    }
    
    int main()
    {
    	FOR(k,0,2){pB[k][0]=1;FOR(i,1,N*N-1)pB[k][i]=pB[k][i-1]*Base[k]%Mod[k];}
    	int T;
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d",&n,&m);
    		FOR(i,1,n)scanf("%s",A[i]+1);
    		scanf("%d%d",&p,&q);
    		FOR(i,1,p)scanf("%s",B[i]+1);
    		if(p>n||q>m){puts("0");continue;}
    		
    		FOR(k,0,2)FOR(i,1,n)FOR(j,1,m)
    			s[k][i][j]=(
    				(s[k][i][j-1]+s[k][i-1][j]-s[k][i-1][j-1]+(A[i][j]-'a'+1)*pB[k][Hs(i,j)])
    				%Mod[k]+Mod[k]
    			)%Mod[k];
    		FOR(k,0,2)
    		{
    			h[k]=0;
    			FOR(i,1,p)FOR(j,1,q)h[k]=(h[k]+(B[i][j]-'a'+1)*pB[k][Hs(i,j)])%Mod[k];
    		}
    		
    		int cnt=0;
    		FOR(i,1,n-p+1)FOR(j,1,n-q+1)
    		{
    			bool flag=1;
    			FOR(k,0,2)if(
    				h[k]*pB[k][Hs(i,j)]%Mod[k]!=S(k,i,j,i+p-1,j+q-1)
    			)flag=0;
    			if(flag)cnt++;
    		}
    		printf("%d
    ",cnt);
    	}
    	return 0;
    }
    
  • 相关阅读:
    django第10天(聚合查询,常用字段)
    django第9天(多表操作)
    django第8天(在测试文件中运行django项目|单表操作)
    django第七天(模板的复用性,include标签和母版)
    django第六天(模板相关,过滤器和标记)
    SparkCore2
    SparkCore
    SQL
    Spark基础
    使用Observer实现HBase到Elasticsearch的数据同步
  • 原文地址:https://www.cnblogs.com/Paulliant/p/10204756.html
Copyright © 2020-2023  润新知