Given an N * M matrix and t p * Q matrix, evaluate the number of sub-matrices of this T matrix that are N * m.
All matrices are 01 matrices, only '0 ''*'
Hash of the matrix. Hash the Q columns in each row to obtain a new matrix, and then hash the P columns in each column. [note that the number of magic values obtained in the hash of the row and column cannot be the same, otherwise it is easy to conflict, wa, preferably two prime numbers]
In this way, each sub-matrix of the original matrix is replaced by a number, and then map is enough to judge.
Note: The hash values of all sub-matrices of the original matrix cannot be stored in the map in advance, and then compared. because the number of sub-matrices is too large, MLE can be used.
The hash value of T matrix should be stored in map. Note that there is a duplicate matrix, and the number of times must be added.
#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<algorithm>#include<map>#include<set>#include<iterator>using namespace std;typedef unsigned long long ull;int ba=131;int ba2=499;char mp[1005][1005];char a[100][100];ull H[1005];ull xp[1005];ull xp2[1005];ull nmp[1005][1005];map<ull,int> s;map<ull,int> ::iterator it;int n,m,t,q,p,ca=1;int main(){ xp2[0]=xp[0]=1; for(int i=1;i<=1001;i++) xp[i]=xp[i-1]*ba,xp2[i]=xp2[i-1]*ba2; while(~scanf("%d%d%d%d%d",&n,&m,&t,&p,&q)) { if(n+m+t+p+q==0) break; s.clear(); int ans=0; for(int i=0;i<n;i++) scanf("%s",mp[i]); while(t--) { for(int i=0;i<p;i++) scanf("%s",a[i]); ull tmp; for(int i=0;i<p;i++) { tmp=0; for(int j=q-1;j>=0;j--) tmp=tmp*ba+a[i][j]; H[i]=tmp; } tmp=0; for(int i=p-1;i>=0;i--) tmp=tmp*ba2+H[i]; s[tmp]++; } for(int i=0;i<n;i++) { H[m]=0; for(int j=m-1;j>=0;j--) H[j]=H[j+1]*ba+mp[i][j]; for(int j=0;j+q<=m;j++) nmp[i][j]=H[j]-H[j+q]*xp[q]; } for(int j=0;j+q<=m;j++) { H[n]=0; for(int i=n-1;i>=0;i--) H[i]=H[i+1]*ba2+nmp[i][j]; for(int i=0;i+p<=n;i++) { it=s.find(H[i]-H[i+p]*xp2[p]); if(it!=s.end()) { ans+=it->second; s.erase(it); } } } printf("Case %d: %d\n",ca++,ans); } return 0;}
Hash of the poj 3690 constellations Matrix