BZOJ 2351: [BeiJing2011]Matrix
来源:互联网 发布:成都php培训机构 编辑:程序博客网 时间:2024/05/18 01:58
2351: [BeiJing2011]Matrix
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 903 Solved: 281
[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。
分析:
考虑hash,就可以实现O(1)查询某个矩阵是否出现过。
但当原矩阵进行hash时,可以利用模数可减的性质,先求前缀和,再减去这个矩阵最上一横排之前的那些行,和左边不包含在这个矩阵中的这些列,再加上左上角被减了2次的小矩阵。
hash果然是靠信仰。 第一次写矩阵HASH的我不要脸地抄了神犇的代码,包括base
自己取的base WA掉了 难过
以及为什么unsigned long long 不行?。。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int N = 1010;const int base1 = 10016957;const int base2 = 10016959;const int mod = 10007;int m,n,a,b,q; unsigned int sum[N][N],power1[N],power2[N];struct node{ int pre; unsigned int w;}edge[N * N];inline int Max(int a,int b){ return a>b?a:b;}int num=0;int head[N*N];void add(int from,unsigned int temp){ num++; edge[num].pre=head[from]; edge[num].w=temp; head[from]=num;}inline void Hash(unsigned int x){ int pos=x%mod; add(pos,x);}inline bool check(unsigned int temp){ int pos=temp%mod; for(register int i=head[pos];i;i=edge[i].pre) if(temp==edge[i].w) return true; return false;} int main(){ scanf("%d%d%d%d",&n,&m,&a,&b); for(register int i=1;i<=n;i++) for(register int j=1;j<=m;j++) scanf("%1d",&sum[i][j]); for(register int i=1;i<=n;i++) for(register int j=1;j<=m;j++) sum[i][j]+=sum[i-1][j]*base1; for(register int i=1;i<=n;i++) for(register int j=1;j<=m;j++) sum[i][j]+=sum[i][j-1]*base2; power1[0]=power2[0]=1; for(register int i=1;i<=max(n,m);i++){ power1[i]=power1[i-1]*base1; power2[i]=power2[i-1]*base2; } for(register int i=a;i<=n;i++){ for(register int j=b;j<=m;j++){ unsigned int temp = sum[i][j] -sum[i-a][j]*power1[a] -sum[i][j-b]*power2[b] +sum[i-a][j-b]*power1[a]*power2[b]; Hash(temp); } } scanf("%d",&q); while(q--){ for(register int i=1;i<=a;i++) for(register int j=1;j<=b;j++) scanf("%1d",&sum[i][j]); for(register int i=1;i<=a;i++) for(register int j=1;j<=b;j++) sum[i][j]+=sum[i-1][j]*base1; for(register int i=1;i<=a;i++) for(register int j=1;j<=b;j++) sum[i][j]+=sum[i][j-1]*base2; unsigned int temp = sum[a][b]; if(check(temp)) printf("1\n"); else printf("0\n"); } return 0;}
- BZOJ 2351: [BeiJing2011]Matrix
- BZOJ 2351 BeiJing2011 Matrix Hash
- BZOJ 2351: [BeiJing2011]Matrix 哈希
- bzoj 2351: [BeiJing2011]Matrix(二维Hash)
- BZOJ 2462/2351 [BeiJing2011]矩阵模板/[BeiJing2011]Matrix 二维哈希
- 【BeiJing2011】【BZOJ2351】Matrix
- [bzoj2351][BeiJing2011]Matrix 哈希
- [BZOJ2351][BeiJing2011]Matrix
- BZOJ 2461: [BeiJing2011]符环
- bzoj 2461: [BeiJing2011]符环
- bzoj 2461: [BeiJing2011]符环
- bzoj 2461: [BeiJing2011]符环
- Bzoj 2460: [BeiJing2011]元素
- BZOJ 2460 [BeiJing2011] 元素
- 【BZOJ】2460: [BeiJing2011]元素
- bzoj 2460 [BeiJing2011]元素
- BZOJ 2553: [BeiJing2011]禁忌
- bzoj 2460: [BeiJing2011]元素
- 操作元素内容,属性,css
- SGD平行算法
- Chrome的版本历史
- 单链表之创建与倒置
- hdu5975(树状数组原理)
- BZOJ 2351: [BeiJing2011]Matrix
- Kitchen-sink 厨房水槽是什么鬼?
- 链表基本排序(逆置、冒泡、选择、插入)
- salesforce零基础学习(七十五)浅谈SOSL(Salesforce Object Search Language)
- 并查集专题: HDU1232畅通工程
- JQuery dom对象与jquery对象相互转换 小案例
- 关于return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask 错误
- 集合深浅拷贝以及经常遇到的坑(面试常问)
- filter拦截器改变字体编码格式