TTTTTTTTTTTTTTTTTTTTT POJ 3690 0与* 二维哈希 模板 +multiset
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 5923 | Accepted: 1164 |
Description
The starry sky in the summer night is one of the most beautiful things on this planet. People imagine that some groups of stars in the sky form so-called constellations. Formally a constellation is a group of stars that are connected together to form a figure or picture. Some well-known constellations contain striking and familiar patterns of bright stars. Examples are Orion (containing a figure of a hunter), Leo (containing bright stars outlining the form of a lion), Scorpius (a scorpion), and Crux (a cross).
In this problem, you are to find occurrences of given constellations in a starry sky. For the sake of simplicity, the starry sky is given as a N× M matrix, each cell of which is a '*' or '0' indicating a star in the corresponding position or no star, respectively. Several constellations are given as a group of T P × Q matrices. You are to report how many constellations appear in the starry sky.
Note that a constellation appears in the sky if and only the corresponding P × Q matrix exactly matches some P × Q sub-matrix in the N ×M matrix.
Input
The input consists of multiple test cases. Each test case starts with a line containing five integers N, M, T, P and Q(1 ≤ N, M ≤ 1000, 1 ≤ T≤ 100, 1 ≤ P, Q ≤ 50).
The following N lines describe the N × M matrix, each of which contains M characters '*' or '0'.
The last part of the test case describe T constellations, each of which takes P lines in the same format as the matrix describing the sky. There is a blank line preceding each constellation.
The last test case is followed by a line containing five zeros.
Output
For each test case, print a line containing the test case number( beginning with 1) followed by the number of constellations appearing in the sky.
Sample Input
3 3 2 2 2
*00
0**
*00 **
00 *0
**
3 3 2 2 2
*00
0**
*00 **
00 *0
0*
0 0 0 0 0
Sample Output
Case 1: 1
Case 2: 2
Source
题意:给定一个n*m矩阵和t个p*q的矩阵,求这t个矩阵有多少个是n*m的子矩阵。
矩阵都是01矩阵,只有'0' '*'
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MM(a,b) memset(a,b,sizeof(a));
const double eps = 1e-;
const int inf =0x7f7f7f7f;
const double pi=acos(-);
const int maxn=+; int ans=inf;
int n,m,t,p,q,cas=;
char text[maxn][maxn];
ull b1[],b2[];
char pat[][];
ull htmp[][],h[][]; ull base1=1e7+7;
ull base2=1e8+7; void init()
{
b1[]=;b2[]=;
for(int i=;i<;i++) b1[i]=b1[i-]*base1;
for(int i=;i<;i++) b2[i]=b2[i-]*base2; } ull calhash1()
{
ull res=;
for(int i=;i<p;i++)
{
ull k=;
for(int j=;j<q;j++)
k=k*base1+pat[i][j];
res=res*base2+k;
}
return res;
} void calhash2()
{
for(int i=;i<n;i++)
{
for(int j=;j<q;j++) htmp[i][j]=j==?text[i][j]:htmp[i][j-]*base1+text[i][j];
for(int j=q;j<m;j++) htmp[i][j]=htmp[i][j-]*base1+text[i][j]-text[i][j-q]*b1[q];
}
for(int j=;j<m;j++)
{
for(int i=;i<p;i++) h[i][j]=i==?htmp[i][j]:h[i-][j]*base2+htmp[i][j];
for(int i=p;i<n;i++) h[i][j]=h[i-][j]*base2+htmp[i][j]-htmp[i-p][j]*b2[p];//求前缀
}
} multiset<ull> st;
int main()
{
init();
int cas=;
while(~scanf("%d%d%d%d%d",&n,&m,&t,&p,&q)&&(n+m+t+p+q))
{
st.clear();
for(int i=;i<n;i++)
scanf("%s",text[i]);
for(int k=;k<t;k++)
{
for(int i=;i<p;i++)
scanf("%s",pat[i]);
st.insert(calhash1());
}
calhash2();
int ans=;
for(int i=p-;i<n;i++)
for(int j=q-;j<m;j++)
st.erase(h[i][j]); printf("Case %d: %d\n",++cas,t-st.size());
}
return ;
}
错误点:
for(int i=p;i<n;i++) h[i][j]=h[i-1][j]*base2+htmp[i][j]-htmp[i-p][j]*b2[p]
刚开始写成了htmp[i][j]=htmp[i-1][j]*base2+htmp[i][j]-htmp[i-p][j]*b2[p]
其实这样是不对的,因为这样的话htmp是代表的前缀,所以一个数会减去多次,,所以需要建立一个新的h数组
wa代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MM(a,b) memset(a,b,sizeof(a));
const double eps = 1e-;
const int inf =0x7f7f7f7f;
const double pi=acos(-);
const int maxn=+; int ans=inf;
int dx[]={-,,,};
int dy[]={,,,-};
int n,m,t,p,q,cas=;
char text[maxn][maxn];
ull b1[],b2[];
char pat[][];
ull has[][];
ull base1=;
ull base2=; void init()
{
b1[]=;b2[]=;
for(int i=;i<;i++) b1[i]=b1[i-]*base1;
for(int i=;i<;i++) b2[i]=b2[i-]*base2; }
ull H[][]; ull calhash1()
{
ull res=;
for(int i=;i<p;i++)
{
ull k=;
for(int j=;j<q;j++)
k=k*base1+pat[i][j];
res=res*base2+k;
}
return res;
} void calhash2()
{
for(int i=;i<n;i++)
{
for(int j=;j<q;j++) has[i][j]=j==?text[i][j]:has[i][j-]*base1+text[i][j];
for(int j=q;j<m;j++) has[i][j]=has[i][j-]*base1+text[i][j]-text[i][j-q]*b1[q];
}
for(int j=;j<m;j++)
{
for(int i=;i<p;i++) has[i][j]=i==?has[i][j]:has[i-][j]*base2+has[i][j];
for(int i=p;i<n;i++) has[i][j]=has[i-][j]*base2+has[i][j]-has[i-p][j]*b2[p];
}
} set<ull> st;
int main()
{
init();
int cas=;
while(~scanf("%d%d%d%d%d",&n,&m,&t,&p,&q)&&(n+m+t+p+q))
{
st.clear();
for(int i=;i<n;i++)
scanf("%s",text[i]);
for(int k=;k<t;k++)
{
for(int i=;i<p;i++)
scanf("%s",pat[i]);
st.insert(calhash1());
}
calhash2();
int ans=;
for(int i=;i<n;i++)
for(int j=;j<m;j++)
if(st.count(has[i][j])) st.erase(has[i][j]); printf("Case %d: %d\n",++cas,t-st.size());
}
return ;
}
TTTTTTTTTTTTTTTTTTTTT POJ 3690 0与* 二维哈希 模板 +multiset的更多相关文章
- C#微信公众号接口开发,灵活利用网页授权、带参数二维码、模板消息,提升用户体验之完成用户绑定个人微信及验证码获取
一.前言 当下微信公众号几乎已经是每个公司必备的,但是大部分微信公众账号用户体验都欠佳,特别是涉及到用户绑定等,需要用户进行复杂的操作才可以和网站绑定,或者很多公司直接不绑定,而是每次都让用户填写账号 ...
- URAL - 1486 Equal Squares 二维哈希+二分
During a discussion of problems at the Petrozavodsk Training Camp, Vova and Sasha argued about who o ...
- hdu1823(二维线段树模板题)
hdu1823 题意 单点更新,求二维区间最值. 分析 二维线段树模板题. 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息. 一般一维线段树是切割某一可变区间直到满足所要查询 ...
- 【URAL 1486】Equal Squares(二维哈希+二分)
Description During a discussion of problems at the Petrozavodsk Training Camp, Vova and Sasha argued ...
- 【BZOJ 2462】矩阵模板 (二维哈希)
题目 给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在 原矩阵中出现过. 所谓01矩阵,就是矩阵中所有元素不是0就是1. 输入 输入文件的第一行为M.N.A.B,参见 ...
- AcWing - 156 矩阵(二维哈希)
题目链接:矩阵 题意:给定一个$m$行$n$列的$01$矩阵$($只包含数字$0$或$1$的矩阵$)$,再执行$q$次询问,每次询问给出一个$a$行$b$列的$01$矩阵,求该矩阵是否在原矩阵中出现过 ...
- hdu 4819 二维线段树模板
/* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits ...
- poj 2155:Matrix(二维线段树,矩阵取反,好题)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17880 Accepted: 6709 Descripti ...
- POJ 2155 Matrix (二维线段树)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17226 Accepted: 6461 Descripti ...
随机推荐
- ADG环境搭建
一:实验环境介绍PC机系统: CentOS 6.5(64位)数据库版本: Oracle 11gR2 11.2.0.4 (64位)IP地址规划:主数据库10.110.9.41 SID:orapridb_ ...
- ASP.NET Core中使用Autofac进行属性注入
一些无关紧要的废话: 作为一名双修程序员(自封的),喜欢那种使用Spring的注解形式进行依赖注入或者Unity的特性形式进行依赖注入,当然,形式大同小异,但结果都是一样的,通过属性进行依赖注入. A ...
- pom.xml标签页名称
pom.xml文件双击打开后,标签页显示的名称与<artifactId></artifactId>的内容相一致.
- CF39H 【Multiplication Table】
这题可以枚举出每个i,j 位置的数>需要用到进制转换 int zh(int x){ long long sum=0,i=0; while(x){ sum=sum+((x%n)*pow(10,i) ...
- std::tr1::function和bind组件
C++中std::tr1::function和bind 组件的使用 在C++的TR1中(Technology Report)中包含一个function模板类和bind模板函数,使用它们可以实现类似函数 ...
- linux 三剑客之sed常用总结
sed 列出5-7行 [root@www ~]# nl /etc/passwd | sed -n '5,7p' -n不在处理前打印,搜索root,/p打印 nl /etc/passwd | sed ' ...
- redis存储数据
redis存储结构--5种 RedisTemplate访问Redis数据结构(一)--String https://blog.csdn.net/qq_25135655/article/details/ ...
- 无障碍开发(三)之ARIA aria-***属性值
aria-***属性值
- GitLab: Deploy keys are not allowed to push code.
被这个问题坑了,大半天.写此博文,愿入坑的童鞋能及时托坑 一.当你第一次pull或者push gitlab远程项目的时候提示你一个该建立一个sshkey,此时你在客户端生成sshkey 二.切记要把这 ...
- CentOS7搭建FastDFS V5.11分布式文件系统(三)
1.测试 前面两篇博文已对FastDFS的安装和配置,做了比较详细的讲解.FastDFS的基础模块都搭好了,现在开始测试下载. 1.1 配置客户端 同样的,需要修改客户端的配置文件: /etc/fdf ...