Constellations
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的更多相关文章

  1. C#微信公众号接口开发,灵活利用网页授权、带参数二维码、模板消息,提升用户体验之完成用户绑定个人微信及验证码获取

    一.前言 当下微信公众号几乎已经是每个公司必备的,但是大部分微信公众账号用户体验都欠佳,特别是涉及到用户绑定等,需要用户进行复杂的操作才可以和网站绑定,或者很多公司直接不绑定,而是每次都让用户填写账号 ...

  2. URAL - 1486 Equal Squares 二维哈希+二分

    During a discussion of problems at the Petrozavodsk Training Camp, Vova and Sasha argued about who o ...

  3. hdu1823(二维线段树模板题)

    hdu1823 题意 单点更新,求二维区间最值. 分析 二维线段树模板题. 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息. 一般一维线段树是切割某一可变区间直到满足所要查询 ...

  4. 【URAL 1486】Equal Squares(二维哈希+二分)

    Description During a discussion of problems at the Petrozavodsk Training Camp, Vova and Sasha argued ...

  5. 【BZOJ 2462】矩阵模板 (二维哈希)

    题目 给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在 原矩阵中出现过. 所谓01矩阵,就是矩阵中所有元素不是0就是1. 输入 输入文件的第一行为M.N.A.B,参见 ...

  6. AcWing - 156 矩阵(二维哈希)

    题目链接:矩阵 题意:给定一个$m$行$n$列的$01$矩阵$($只包含数字$0$或$1$的矩阵$)$,再执行$q$次询问,每次询问给出一个$a$行$b$列的$01$矩阵,求该矩阵是否在原矩阵中出现过 ...

  7. hdu 4819 二维线段树模板

    /* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits ...

  8. poj 2155:Matrix(二维线段树,矩阵取反,好题)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17880   Accepted: 6709 Descripti ...

  9. POJ 2155 Matrix (二维线段树)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17226   Accepted: 6461 Descripti ...

随机推荐

  1. 蚂蚁分类信息商家发布文章、商品外链及远程图片自动添加nofollow属性

    蚂蚁商户发布文章.商品是可以添加外链或者直接用外部图片,但是这对分类网站运营不利. 所以要对外链进行过滤,演示网站保洁,蚂蚁分类的源码. 下面就说下怎么处理自动给外链自动加上nofollow属性. 1 ...

  2. 如何用纯 CSS 创作六边形按钮特效

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/xjoOeM 可交互视频教 ...

  3. [Next] 三.next自定义服务器和路由

    next 服务端渲染 实际上,next 一直都是执行的服务端渲染.npm start执行的是 next 自带的服务器来运行你的应用.next 是支持自定义服务器的,同时能够支持现有的路由和模式,你可以 ...

  4. JSTL标签+El表达式把list集合数据展示到 JSP页面

    JSP页面 <%@ page import="cn.itcast.domain.User" %><%@ page import="java.util.L ...

  5. springboot(十九)-线程池的使用

    我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行. 话不多说,编码开始: 1.创建spri ...

  6. whistle 前端工具之抓包利器

    一.业务场景 前端本地开发的场景中,我们需要频繁的改动代码,并需要实时看到效果,并且在一些开发场景中,我们需要将特定的请求代理到特定的IP.本地文件等,所以使用fiddler或whistle等本地.真 ...

  7. 关于catopen函数

    关于catopen函数: 参考网址:http://pubs.opengroup.org/onlinepubs/009695399/functions/catopen.html 1)编辑消息文件 [ro ...

  8. 关于sqlmap的两个小坑

    i春秋作家:__LSA__ 0x00 概述 近日在利用sqlmap注入测试时遇到一个奇怪的现象,高版本sqlmap无法检测出注入,但是低版本的可以测出注入,并且能跑出数据不是误报,经过对比测试和查看s ...

  9. Nginx如何配置反向代理

    server { listen 80; server_name 代理域名; location / { proxy_pass 应用域名:应用端口; proxy_set_header Host $host ...

  10. 配置jupyter notebook网页浏览

    上一篇博文已经介绍安装了Anaconda3:https://www.cnblogs.com/hello-wei/p/10233192.html jupyter notebook [I 11:33:11 ...