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 ...
随机推荐
- AcWing175电路维修
这是一道在luogu的蓝题,在yxc大佬的讲解下AC掉了(百般调试) 首先这道题给了一个字符串矩阵,/ \表示相连哪两个节点,只可以走/ \所连接的两个点,但我们可以旋转每一个边,询问从1,1 走到 ...
- centos7 上pip install mysqlclient的时候报错OSError: mysql_config not found,
yum install mysql-devel gcc gcc-devel python-devel
- 用css、如何让图片自动适应屏幕大小,不出现滚动条,不变形,兼容各个浏览器?急!!!
如果是个背景图的话,定义一个div,高100%,宽100%,里面放个img<div class='bg'> <img src="images/bg.jpg" al ...
- 牛客 545A 小A与最大子段和 & CF 660F Bear and Bowling 4
大意: 给定序列$a$, 求选择一个子区间$[l,r]$, 使得$\sum\limits_{i=l}^r(i-l+1)a_i$最大. $n\le2e5, |a_i|\le 1e7$. 记$s[i]=\ ...
- Spring经典高频面试题,原来是长这个样子
Spring经典高频面试题,原来是长这个样子 2019年08月23日 15:01:32 博文视点 阅读数 719 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文 ...
- easyui在table单元格中添加进度条
function XR_jd(alue, rowData, rowIndex){ var value; ...... var htmlstr = '<div class="easyui ...
- 构造器(Constructor)--构造函数
构造器是类型的成员之一,其他成员比如,成员字段,成员函数.狭义上,构造器指的是实例构造器(instance constructor) class Student { public int ID; pu ...
- java实现spark常用算子之filter
import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.a ...
- html/css弹性布局的几大常用属性详解
弹性布局的名称概念: 1.容器:需要添加弹性布局的父元素:项目:弹性布局容器中的每一个子元素,称为项目. 2.主轴:在弹性布局中,我们会通过属性规定水平/垂直方向(flex-direction)为主轴 ...
- Win7下配置IIS服务器以及网站发布
本文摘至于:http://heavengate.blog.163.com/blog/static/202381053201391111512986/ 1.vsual Studio 2010下利用本地I ...