HNU13383:The Big Painting

Problem description

Samuel W. E. R. Craft is an artist with a growing reputation. Unfortunately, the paintings he sells do not provide him enough money for his daily expenses plus the new supplies he needs. He had a brilliant idea yesterday when he ran out of blank canvas: "Why don’t I create a gigantic new painting, made of all the unsellable paintings I have, stitched together?". After a full day of work, his masterpiece was complete.
That’s when he received an unexpected phone call: a client saw a photograph of one of his paintings and is willing to buy it now! He had forgotten to tell the art gallery to remove his old works from the catalog! He would usually welcome a call like this, but how is he going to find his old work in the huge figure in front of him?
Given a black-and-white representation of his original painting and a black-and-white representation of his masterpiece, can you help S.W.E.R.C. identify in how many locations his painting might be?


Input


Output

A single integer representing the number of possible locations where his painting might be.


Sample Input
4 4 10 10
oxxo
xoox
xoox
oxxo
xxxxxxoxxo
oxxoooxoox
xooxxxxoox
xooxxxoxxo
oxxoxxxxxx
ooooxxxxxx
xxxoxxoxxo
oooxooxoox
oooxooxoox
xxxoxxoxxo
Sample Output
4
Problem Source

HNU Contest 


题意:

给出两个图,问大图中包含几个小图


思路:

用数字保存是一种方法,本以为超类型肯定不行的,没有想到居然也能AC,不知道是数据水还是数据保存方面的一些玄机?


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;

#define ls 2*i
#define rs 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define ULL unsigned long long
#define N 2005
#define INF 0x3f3f3f3f
#define EXP 1e-8
#define rank rank1
const int mod = 1000000007;

int h1,h2,w1,w2,ans;
char s1[N][N],s2[N][N];
const ULL t1 = 7;
const ULL t2 = 11;
ULL sum,a[N][N],b[N][N];

void solve()//把大图用数字表示的同时找出与小图相等的位置
{
    int i,j,k;
    ULL x=1;
    for(i = 0; i<w1; i++) x*=t1;
    for(i = 0; i<h2; i++)
    {
        ULL s = 0;
        for(j = 0; j<w1; j++) s = s*t1+s2[i][j];
        a[i][w1-1] = s;
        for(j = w1; j<w2; j++)
            a[i][j] = a[i][j-1]*t1-s2[i][j-w1]*x+s2[i][j];
    }
    x = 1;
    for(i = 0; i<h1; i++) x*=t2;
    for(i = w1-1; i<w2; i++)
    {
        ULL s = 0;
        for(j = 0; j<h1; j++) s = s*t2+a[j][i];
        b[h1-1][i] = s;
        if(s==sum) ans++;
        for(j = h1; j<h2; j++)
        {
            b[j][i] = b[j-1][i]*t2-a[j-h1][i]*x+a[j][i];
            if(b[j][i]==sum) ans++;
        }
    }
}

int main()
{
    int i,j,k;
    while(~scanf("%d%d%d%d",&h1,&w1,&h2,&w2))
    {
        for(i = 0; i<h1; i++) scanf("%s",s1[i]);
        for(i = 0; i<h2; i++) scanf("%s",s2[i]);
        sum = 0;
        for(i = 0; i<h1; i++)//把小图用数字表示
        {
            ULL s = 0;
            for(j = 0; j<w1; j++)
            {
                s = s*t1+s1[i][j];
            }
            sum = sum*t2+s;
        }
        ans = 0;
        solve();
        printf("%d\n",ans);
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值