首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

POJ 3690 Constellations 简略hash

2012-09-23 
POJ 3690 Constellations简单hash题目大意就是给出一个n * m的矩阵,矩阵中只有一些*或者0n 1000, m

POJ 3690 Constellations 简单hash

题目大意就是给出一个n * m的矩阵,矩阵中只有一些*或者0

n <= 1000, m <= 1000

然后有t (t <= 100)个询问,每次询问给出一个p * q的矩阵

p,q是提前固定的数值。

问这些询问中能是大矩阵的子矩阵的有几个


由于p , q都小于50,而且矩阵中只有两个字符

不由得让我们联想到了,把每一行给hash成一个long long 的二进制数

首先,我们把大矩阵每个位置为起点的q长度的串hash成二进制数都存起来

每次询问的时候,把小矩阵每一行给hash了

然后在大矩阵中枚举位置,进行匹配


#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <cmath>#include <queue>#include <map>#include <set>#define MAXN 111111#define MAXM 555555#define INF 100000011#define lch(x) x<<1#define rch(x) x<<1|1#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define eps 1e-7using namespace std;long long h[1111][1111];int n, m, t, p, q;char mp[1111][1111], tmp[66];long long a[66];bool ok(){    for(int i = 0; i + p - 1 < n; i++)        for(int j = q - 1; j < m; j++)        {            int flag = 1;            for(int k = 0; k < p; k++)                if(h[i + k][j] != a[k])                {                    flag = 0;                    break;                }            if(flag) return true;        }    return false;}int main(){    int cas = 0;    while(scanf("%d %d %d %d %d", &n, &m, &t, &p, &q) != EOF)    {        if(!n && !m && !t && !q && !p) break;        for(int i = 0; i < n; i++) scanf("%s", mp[i]);        memset(h, 0, sizeof(h));        for(int i = 0; i < n; i++)            for(int j = 0; j < q; j++)            {                if(mp[i][j] == '*') h[i][q - 1] |= (1LL << j);            }        for(int i = 0; i < n; i++)            for(int j = q; j < m; j++)            {                if(mp[i][j - q] == '*') h[i][j] = h[i][j - 1] - 1LL;                else h[i][j] = h[i][j - 1];                h[i][j] >>= 1LL;                if(mp[i][j] == '*') h[i][j] |= (1LL << (q - 1));            }        int cnt = 0;        while(t--)        {            for(int i = 0; i < p; i++)            {                scanf("%s", tmp);                a[i] = 0;                for(int j = 0; j < q; j++)                    if(tmp[j] == '*') a[i] |= (1LL << j);            }            if(ok()) cnt++;        }        printf("Case %d: %d\n", ++cas, cnt);    }    return 0;}


热点排行