bzoj2351(矩阵哈希)
4753: Lydsy2351 Matrix
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 97 Solved: 33
[Submit][Status][Web Board]
Description
给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在原矩阵中出现过。
所谓01矩阵,就是矩阵中所有元素不是0就是1。
所谓01矩阵,就是矩阵中所有元素不是0就是1。
Input
输入文件的第一行为M、N、A、B,参见题目描述。
接下来M行,每行N个字符,非0即1,描述原矩阵。
接下来一行为你要处理的询问数Q。
接下来Q个矩阵,一共Q*A行,每行B个字符,描述Q个01矩阵。
A ≤ 100
接下来M行,每行N个字符,非0即1,描述原矩阵。
接下来一行为你要处理的询问数Q。
接下来Q个矩阵,一共Q*A行,每行B个字符,描述Q个01矩阵。
A ≤ 100
Output
你需要输出Q行,每行为0或者1,表示这个矩阵是否出现过,0表示没有出现过,1表示出现过。
Sample Input
3 3 2 2
111
000
111
3
11
00
11
11
00
11
Sample Output
1
0
1
我只能说进阶指南的标程太坑,,,,,,非但复杂看不懂还是错的,,,,毒害身心,,浪费了我两天下午的时间
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int maxn=1010; const int pc=131; const int ppc=13331; const int mod=10100; unsigned int a[maxn][maxn],p1[maxn],p2[maxn],sum[maxn][maxn]; int fa,adj[mod]; char b[maxn][maxn]; struct my{ unsigned int zhi; int next; }bian[maxn*maxn+5]; void Hash(unsigned int u){ int x=u%mod; bian[++fa].zhi=u; bian[fa].next=adj[x]; adj[x]=fa; } bool ask(unsigned int u){ int x=u%mod; for (int i=adj[x];i;i=bian[i].next){ if(bian[i].zhi==u) return true; } return false; } int main(){ int n,m,r,c,q; cin>>m>>n>>r>>c; for (int i=1;i<=m;i++) scanf("%s",b[i]+1); cin>>q; for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) sum[i][j]=b[i][j]-'0'; for (int i=1;i<=m;i++){ for (int j=1;j<=n;j++){ sum[i][j]+=sum[i-1][j]*pc; } } for (int i=1;i<=m;i++){ for (int j=1;j<=n;j++){ sum[i][j]+=sum[i][j-1]*ppc; } } p1[0]=p2[0]=1; for (int i=1;i<=r;i++) p1[i]=p1[i-1]*pc; for (int j=1;j<=c;j++) p2[j]=p2[j-1]*ppc; for (int i=r;i<=m;i++){ for (int j=c;j<=n;j++){ unsigned int temp=sum[i][j]-sum[i-r][j]*p1[r]-sum[i][j-c]*p2[c]+sum[i-r][j-c]*p1[r]*p2[c]; Hash(temp); } } while(q--){ memset(sum,0,sizeof(sum)); memset(b,0,sizeof(b)); for (int i=1;i<=r;i++) scanf("%s",b[i]+1); for (int i=1;i<=r;i++){ for (int j=1;j<=c;j++){ sum[i][j]=b[i][j]-'0'; } } for (int i=1;i<=r;i++) for (int j=1;j<=c;j++) sum[i][j]+=sum[i-1][j]*pc; for (int i=1;i<=r;i++) for (int j=1;j<=c;j++) sum[i][j]+=sum[i][j-1]*ppc; unsigned int temp=sum[r][c]; if(ask(temp)) puts("1"); else puts("0"); } return 0; }