题解 P3585 【[POI2015]PIE】

· · 题解

一道比较水的模拟题,思路很好想,代码也很好写,码量并不大。

具体思路如下:遍历印章,找到印章中的第一个x并以这个x为参考系,将其他x与这个x的相对坐标存到一个数组之中。接下来就遍历需要印出的图案,每遇到一个x就立马以这个x为参考系,看看能否和印章吻合,如果不能的话立马跳出,说明这个图案永远无法由这个印章构成,如果能的话就将与印章吻合的所有x都变为.,然后继续比对,直至所有x都被印章吻合之后,说明这个图案可以被该印章构成。

以下是代码(略显繁琐,可以精简)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e3 + 5;
const int M = 1e6 + 5;
char Map[N][N];
char Stamp[N][N];
int stax;
int stay;
struct Node{
    int x;
    int y;
}relative[M];
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        memset(relative, 0, sizeof relative);
        int n, m;
        scanf("%d%d", &n, &m);
        int a, b;
        scanf("%d%d", &a, &b);
        for (int i = 1; i <= n;i++)
            for (int j = 1; j <= m;j++)
                cin >> Map[i][j];
        bool flag = false;
        int cnt = 0;
        for (int i = 1; i <= a;i++)
        {
            for (int j = 1; j <= b;j++)
            {
                cin >> Stamp[i][j];
                if(Stamp[i][j]=='x')
                {
                    if(!flag)
                        stax = i, stay = j;
                    else
                        relative[++cnt].x = i - stax, relative[cnt].y = j - stay;
                    flag = true;
                }
            }
        }
        bool can = true;
        for (int i = 1; i <= n;i++)
        {
            for (int j = 1; j <= m;j++)
            {
                if (Map[i][j] == 'x')
                {
                    for (int k = 1; k <= cnt;k++)
                    {
                        int xx = i + relative[k].x;
                        int yy = j + relative[k].y;
                        if(xx<1||xx>n||yy<1||yy>m)
                        {
                            can = false;
                            break;
                        }
                        if(Map[xx][yy]!='x')
                        {
                            can = false;
                            break;
                        }
                    }
                    if(can)
                    {
                        for (int k = 1; k <= cnt;k++)
                        {
                            int xx = i + relative[k].x;
                            int yy = j + relative[k].y;
                            Map[xx][yy] = '.';
                        }
                    }
                }
                if(!can)
                    break;
            }
            if(!can)
                    break;
        }
        if(!can)
            puts("NIE");
        else
            puts("TAK");
    }
    return 0;
}