BZOJ-2462&&2351 矩阵模板&&Matrix 暴力 or Hash orAC自动机 or KMP
来源:互联网 发布:教育行业网络推广方案 编辑:程序博客网 时间:2024/05/20 15:59
2462: [BeiJing2011]矩阵模板
Time Limit: 2 Sec Memory Limit: 128 MB
Submit: 717 Solved: 316
[Submit][Status][Discuss]
Description
给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在
原矩阵中出现过。
所谓01矩阵,就是矩阵中所有元素不是0就是1。
Input
输入文件的第一行为M、N、A、B,参见题目描述。
接下来M行,每行N个字符,非0即1,描述原矩阵。
接下来一行为你要处理的询问数Q。
接下来Q个矩阵,一共Q*A行,每行B个字符,描述Q个01矩阵。
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
HINT
对于100%的数据,A < = 100。
Source
Day4
.
2351: [BeiJing2011]Matrix
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 740 Solved: 212
[Submit][Status][Discuss]
Description
给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在原矩阵中出现过。
所谓01矩阵,就是矩阵中所有元素不是0就是1。
Input
输入文件的第一行为M、N、A、B,参见题目描述。
接下来M行,每行N个字符,非0即1,描述原矩阵。
接下来一行为你要处理的询问数Q。
接下来Q个矩阵,一共Q*A行,每行B个字符,描述Q个01矩阵。
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
HINT
对于100%的实际测试数据,M、N ≤ 1000,Q = 1000
对于40%的数据,A = 1。
对于80%的数据,A ≤ 10。
对于100%的数据,A ≤ 100。
Source
题解
2351是2462的数据强化版,对于2462,可以直接暴力;
自己的写法是,记录了一下矩形的0的数目,用二维树状数组的思路,求出子矩阵的0的数目,询问时先比较数目再一一比对;
2462就必须换方法了,这里用的是hash,在做的时候,考虑到了hash,但YY出问题了,大体的思路是:
把每行展成字符串,总之,读入大的矩阵,把大矩阵的每个子矩阵hash,(每个子矩阵的hash值和暴力优化的那个思想很类似),这样每次读入小矩阵可以直接同样的方法hash,与大矩阵的子矩阵比较即可。至于hash的重合概率,TA学长粗略计算是10^-3级的,所以几乎可以无视
同时可以用KMP或者AC自动机的方法,大体就是把一个矩阵的一行或者一列当作一个字符,来实现字符的匹配,自己并不是很会。
code1:(自己的暴力P2462)
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f;}int n,m,a,b,q;struct matr{ int a[1010][1010]; int nn,mm; int num0[1010][1010]; matr(){memset(a,0,sizeof(a));memset(num0,0,sizeof(num0));}};struct matri{ int a[110][110]; int nn,mm; int num0[110][110]; matri(){memset(a,0,sizeof(a));memset(num0,0,sizeof(num0));}};matri Mat[1010]; matr Ma;bool pd(int x,int y,int lx,int ly,int now){ bool f=1; for (int i=x-lx+1; i<=x; i++) for (int j=y-ly+1; j<=y; j++) if (Ma.a[i][j]!=Mat[now].a[(i-x+lx)][(j-y+ly)]) {f=0;break;} return f;}void solve(int now){ bool f=0; int aa=Mat[now].nn,bb=Mat[now].mm;int nn0=Mat[now].num0[aa][bb]; //printf("aa=%d bb=%d\n",aa,bb); for (int i=aa; i<=n; i++) for (int j=bb; j<=m; j++) { int n0=Ma.num0[i][j]-Ma.num0[i-aa][j]-Ma.num0[i][j-bb]+Ma.num0[i-aa][j-bb]; if (n0==nn0) f=pd(i,j,aa,bb,now); //printf("NOW=%d i=%d j=%d n0=%d nn0=%d F=%d\n",now,i,j,n0,nn0,f); if (f==1) {puts("1");return;} } puts("0");}int main(){ n=read();m=read(); a=read();b=read(); Ma.nn=n; Ma.mm=m; for (int i=1; i<=n; i++) { char aaa[1010]; scanf("%s",aaa); for (int j=1; j<=m; j++) Ma.a[i][j]=aaa[j-1]-'0'; } for (int i=1; i<=n; i++) for (int j=1; j<=m; j++) if (!Ma.a[i][j]) Ma.num0[i][j]=Ma.num0[i-1][j]+Ma.num0[i][j-1]-Ma.num0[i-1][j-1]+1; else Ma.num0[i][j]=Ma.num0[i-1][j]+Ma.num0[i][j-1]-Ma.num0[i-1][j-1]; q=read(); for (int i=1; i<=q; i++) { Mat[i].nn=a; Mat[i].mm=b; for (int j=1; j<=a; j++) { char aaa[1010]; scanf("%s",aaa); for (int k=1; k<=b; k++) { Mat[i].a[j][k]=aaa[k-1]-'0'; if (!Mat[i].a[j][k]) Mat[i].num0[j][k]=Mat[i].num0[j-1][k]+Mat[i].num0[j][k-1]-Mat[i].num0[j-1][k-1]+1; else Mat[i].num0[j][k]=Mat[i].num0[j-1][k]+Mat[i].num0[j][k-1]-Mat[i].num0[j-1][k-1]; } } } for (int i=1; i<=q; i++) solve(i); return 0;}
code2:(hash,P2351)by TA学长
#include<cstdio>#include<iostream>using namespace std;#include<cstring>#include<algorithm>const int M=1000+5,N=1000+5,A=100+5,B=1000+5;const int Mod=1e9+7;int mat[N][M];typedef long long LL;int hash[2][N][M],data[N*M];int main(){// freopen("matrix.in","r",stdin);// freopen("matrix.out","w",stdout); int m,n,a,b; scanf("%d%d%d%d",&n,&m,&a,&b); char c; for(int i=0;i<n;++i) for(int j=0;j<m;++j){ c=getchar(); while(c<'0'||c>'1')c=getchar(); mat[i][j]=c-'0'; } LL base[2]={1,1}; for(int i=b;i--;)base[0]=(base[0]<<1)%Mod; for(int i=n;i--;){ for(int j=1;j<=b;++j)hash[0][i][m-b]=((hash[0][i][m-b]<<1)+mat[i][m-j])%Mod; for(int j=m-b-1;j>=0;--j)hash[0][i][j]=((hash[0][i][j+1]<<1)%Mod-mat[i][j+b]*base[0]+mat[i][j])%Mod; //for(int j=m-b;j>=0;--j)printf("hash(0,%d,%d)=%d\n",i,j,hash[0][i][j]); } for(int i=a;i--;)base[1]=base[1]*base[0]%Mod; for(int j=m-b;j>=0;--j){ for(int i=1;i<=a;++i)hash[1][n-a][j]=(hash[1][n-a][j]*base[0]+hash[0][n-i][j])%Mod; for(int i=n-a-1;i>=0;--i)hash[1][i][j]=(hash[1][i+1][j]*base[0]-hash[0][i+a][j]*base[1]+hash[0][i][j])%Mod; } int tot=0; for(int i=n-a;i>=0;--i) for(int j=m-b;j>=0;--j){ data[tot++]=(hash[1][i][j]+Mod)%Mod; //printf("hash(1,%d,%d)=%d\n",i,j,data[tot-1]); } sort(data,data+tot); tot=unique(data,data+tot)-data; int q,tmp; scanf("%d",&q); while(q--){ tmp=0; for(int i=0;i<a;++i) for(int j=0;j<b;++j){ c=getchar(); while(c<'0'||c>'1')c=getchar(); mat[i][j]=c-'0'; } for(int i=a;i--;) for(int j=b;j--;) tmp=((tmp<<1)+mat[i][j])%Mod; //printf("%d\n",tmp); if(data[lower_bound(data,data+tot,tmp)-data]==tmp)puts("1"); else puts("0"); }}
- BZOJ-2462&&2351 矩阵模板&&Matrix 暴力 or Hash orAC自动机 or KMP
- [BZOJ 2462 BeiJing2011矩阵模板]矩阵Hash
- bzoj 2462 [BeiJing2011]矩阵模板 (hash)
- [BZOJ]2462: [BeiJing2011]矩阵模板 二维hash
- [BZOJ2462]矩阵模板(暴力||矩阵hash)
- Codeforces 486B OR in Matrix(暴力)
- BZOJ 2462 BeiJing 2011 矩阵模板 二维hash
- BZOJ 2462 BeiJing 2011 矩阵模板 二维hash
- BZOJ 2351 BeiJing2011 Matrix Hash
- BZOJ 2351 Matrix (Hash)
- BZOJ 2462/2351 [BeiJing2011]矩阵模板/[BeiJing2011]Matrix 二维哈希
- HDU1711 Number Sequence【机智 or KMP模板】
- SUDT 3926 bLue的二叉树 [KMP or hash]【思维】
- bzoj 3916 暴力+hash
- bzoj 2351: [BeiJing2011]Matrix(二维Hash)
- poj 3233 Matrix Power Series 矩阵快速幂or二分
- KMP && AC自动机模板
- 矩阵hash + KMP
- 防止 jsp被sql注入
- 文本聚类——Kmeans
- 如何在Caffe中配置每一个层的结构
- Perfect Squares
- linux内存寻址解析
- BZOJ-2462&&2351 矩阵模板&&Matrix 暴力 or Hash orAC自动机 or KMP
- Laravel--Facades门面
- 【读书笔记】《R语言实战》Day1
- PHP代码优化
- android基础课之Progress
- java毕向东听课笔记5(构造函数间的调用)
- 4种Java引用浅解
- autocomplete 插件用法和用js实现autocomplete
- Java线程同步-牛逼的线程同步实现