3750: [POI2015]Pieczęć

来源:互联网 发布:新南威尔士预科 知乎 编辑:程序博客网 时间:2024/06/08 00:38

3750: [POI2015]Pieczęć

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 193  Solved: 114
[Submit][Status][Discuss]

Description

一张n*m的方格纸,有些格子需要印成黑色,剩下的格子需要保留白色。
你有一个a*b的印章,有些格子是凸起(会沾上墨水)的。你需要判断能否用这个印章印出纸上的图案。印的过程中需要满足以下要求:
(1)印章不可以旋转。
(2)不能把墨水印到纸外面。
(3)纸上的同一个格子不可以印多次。

Input

第一行一个整数q(1<=q<=10),表示测试点数量。
接下来q个测试点,每个测试点中:
第一行包含4个整数n,m,a,b(1<=n,m,a,b<=1000)。
接下来n行,每行m个字符,描述纸上的图案。'.'表示留白,'x'表示需要染黑。
接下来a行,每行b个字符,描述印章。'.'表示不沾墨水,'x'表示沾墨水。

Output

对于每个测试点,输出TAK(是)或NIE(否)。

Sample Input

2
3 4 4 2
xx..
.xx.
xx..
x.
.x
x.
..
2 2 2 2
xx
xx
.x
x.

Sample Output

TAK
NIE

HINT

Source

鸣谢Jcvb

[Submit][Status][Discuss]

从左上往右下逐个搜索,假如纸上这个位置是墨水,显然是对应着印章第一个出现墨点的位置了
只需暴力check一下当前是否合法即可
#include<iostream>#include<cstdio>#include<cstring>#include<vector>using namespace std; const int maxn = 1001; struct Vector{    int x,y; Vector(){}    Vector(int x,int y): x(x),y(y){}}; int T,n,m,r,c,_x,_y;bool bo[maxn][maxn];char s[maxn][maxn]; vector <Vector> v; bool Del(int x,int y){    for (int i = 0; i < v.size(); i++)    {        int xx = x + v[i].x,yy = y + v[i].y;        if (xx < 1 || xx > n || yy < 1 || yy > m) return 0;        if (!bo[xx][yy]) return 0; bo[xx][yy] = 0;    }    return 1;} void Clear() {memset(bo,0,sizeof(bo)); v.clear(); _x = _y = 0;} int main(){    #ifdef DMC        freopen("DMC.txt","r",stdin);    #endif         cin >> T;    while (T--)    {        scanf("%d%d%d%d",&n,&m,&r,&c);        for (int i = 1; i <= n; i++)        {            scanf("%s",s[i] + 1);            for (int j = 1; j <= m; j++)                if (s[i][j] == 'x') bo[i][j] = 1;        }        for (int i = 1; i <= r; i++)        {            scanf("%s",s[i] + 1);            for (int j = 1; j <= c; j++)            {                if (s[i][j] != 'x') continue;                if (!_x) _x = i,_y = j;                v.push_back(Vector(i - _x,j - _y));            }        }        if (!_x)        {            bool flag = 1;            for (int i = 1; i <= n && flag; i++)                for (int j = 1; j <= m; j++)                    if (bo[i][j]) {flag = 0; break;}            puts(flag ? "TAK" : "NIE"); Clear(); continue;        }                 bool flag = 1;        for (int i = 1; i <= n && flag; i++)            for (int j = 1; j <= m; j++)            {                if (!bo[i][j]) continue;                if (!Del(i,j)) {flag = 0; break;}            }        for (int i = 1; i <= n && flag; i++)            for (int j = 1; j <= m; j++)                if (bo[i][j]) {flag = 0; break;}        puts(flag ? "TAK" : "NIE"); Clear();    }    return 0;}

0 0
原创粉丝点击