码迷,mamicode.com
首页 > 其他好文 > 详细

[POI2015]PIE

时间:2018-05-31 19:12:11      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:直接   提交   spl   std   字符   fread   reg   class   地方   

 

 

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1: 
2
3 4 4 2
xx..
.xx.
xx..
x.
.x
x.
..
2 2 2 2
xx
xx
.x
x.
输出样例#1: 
TAK
NIE
 

说明

一张n*m的方格纸,有些格子需要印成黑色,剩下的格子需要保留白色。

你有一个a*b的印章,有些格子是凸起(会沾上墨水)的。你需要判断能否用这个印章印出纸上的图案。印的过程中需要满足以下要求:

(1)印章不可以旋转。

(2)不能把墨水印到纸外面。

(3)纸上的同一个格子不可以印多次。

 

提交地址 : Luogu3585;

 

模拟水题

调了半天(真是半天);

首先,我们肯定要把印章的左上角第一个有印的地方,对准画布上第一个左上角地方;

显然可以暴力O(n^4), T飞;

 

技术分享图片
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

inline char nc()
{
    static const int BS = 1 << 22;
    static unsigned char buf[BS],*st,*ed;
    if(st == ed) ed = buf + fread(st=buf,1,BS,stdin);
    return st == ed ? EOF : *st++;
}
//#define getchar nc
inline int read()
{
    int res=0;bool flag=0;char ch=getchar();
    while(!isdigit(ch)){if(ch==-)flag=1;ch=getchar();
    }while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch-0);ch=getchar();
    }return flag?-res:res;
}

int q;
int n, m, x, y;
int a[1010][1010];
int tab[1010][1010];
int num, fx, fy;

bool check(int xx, int yy)
{
    xx -= fx - 1, yy -= fy - 1;
    for (register int i = 1 ; i <= x ; i ++)
    {
        for (register int j = 1 ; j <= y ; j ++)
        {
            if (tab[i][j] == 0) continue; 
            if (xx + i - 1 <= 0 or xx + i - 1 > n or yy + j - 1 <= 0 or yy + j - 1 > m or a[xx+i-1][yy+j-1] == 0) return 0;
            a[xx+i-1][yy+j-1] = 0;
            num--;
        }
    }
    return 1;
}

int main()
{
    q = read();
    while (q--)
    {
        num=0;
        n=read(), m=read(), x=read(), y=read();
        fx = fy = 0;
        for (register int i = 1 ; i <= n ; i ++)
        {
            for (register int j = 1 ; j <= m ; j ++)
            {
                char ch;
                cin >> ch;
                if (ch == .) a[i][j] = 0;
                else a[i][j] = 1, num++;
            }
        }
        for (register int i = 1 ; i <= x ; i ++)
        {
            for (register int j = 1 ; j <= y ; j ++)
            {
                char ch;
                cin >> ch;
                if (ch == .) tab[i][j] = 0;
                else
                {
                     tab[i][j] = 1;
                     if (!fx) fx = i, fy = j;
                }                
            }
        }
        
        for (register int i = 1 ; i <= n ; i ++)
        {
            for (register int j = 1 ; j <= m ; j ++)
            {
                if (!a[i][j]) continue;
                if (!check(i, j))
                {
                    puts("NIE");
                    goto End;
                }
                if (num == 0)
                {
                    puts("TAK");
                    goto End;
                }
            }
        }
        puts("NIE");
        End:;
    }
    return 0;
}
zZhBr

 

 

现在我们考虑优化;

我们把时间主要浪费在哪里了?

不停地循环找印章!

显然我们在印章和图里有很多不需要的点, 我们花费了太多时间浪费在它们身上;

那不如干脆来一个链表,直接把有用的点穿起来,这样查询十分省时间!

轻松A掉

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 using namespace std;
  6 
  7 inline char nc()
  8 {
  9     static const int BS = 1 << 22;
 10     static unsigned char buf[BS],*st,*ed;
 11     if(st == ed) ed = buf + fread(st=buf,1,BS,stdin);
 12     return st == ed ? EOF : *st++;
 13 }
 14 #define nc getchar
 15 inline int read()
 16 {
 17     int res=0;bool flag=0;char ch=nc();
 18     while(!isdigit(ch)){if(ch==-)flag=1;ch=nc();
 19     }while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch-0);ch=nc();
 20     }return flag?-res:res;
 21 }
 22 
 23 int q;
 24 int n, m, x, y;
 25 struct MAP
 26 {
 27     int x, y;
 28 }a[1010*1010];
 29 int cnt = 1;
 30 struct TAB
 31 {
 32     int x, y;
 33 }tab[1010*1010];
 34 int now = 1;
 35 int mp[1010][1010];
 36 
 37 inline bool check(int xx, int yy)
 38 {
 39     xx -= tab[1].x - 1, yy -= tab[1].y - 1;
 40     for (register int i = 1 ; i <= now ; i ++)
 41     {
 42         int tx = xx + tab[i].x - 1, ty = yy + tab[i].y - 1;
 43         if (tx <= 0 or tx > n or ty <= 0 or ty > m) return 0;
 44         if (mp[tx][ty] == 0) return 0;
 45         mp[tx][ty] = 0;
 46     }
 47     return 1;
 48 }
 49 
 50 int main()
 51 {
 52     q = read();
 53     while (q--)
 54     {
 55         n=read(), m=read(), x=read(), y=read();
 56         cnt = now = 1;
 57         for (register int i = 1 ; i <= n ; i ++)
 58         {
 59             for (register int j = 1 ; j <= m ; j ++)
 60             {
 61                 char ch;
 62                 cin >> ch;
 63                 if (ch == .) mp[i][j] = 0;
 64                 else 
 65                 {
 66                     mp[i][j] = 1;
 67                     a[cnt].x = i;
 68                     a[cnt++].y = j;
 69                 }
 70             }
 71         }
 72         for (register int i = 1 ; i <= x ; i ++)
 73         {
 74             for (register int j = 1 ; j <= y ; j ++)
 75             {
 76                 char ch;
 77                 cin >> ch;
 78                 if (ch == .) continue;
 79                 else
 80                 {
 81                      tab[now].x = i;
 82                      tab[now++].y = j;
 83                 }                
 84             }
 85         }
 86         cnt--, now--;
 87         for (register int i = 1 ; i <= cnt ; i ++)
 88         {
 89             if (mp[a[i].x][a[i].y] == 0) continue;
 90             if (!check(a[i].x, a[i].y))
 91             {
 92                 puts("NIE");
 93                 goto End;
 94             }
 95         }
 96         
 97         puts("TAK");
 98         End:;
 99     }
100     return 0;
101 }

 

 

[POI2015]PIE

标签:直接   提交   spl   std   字符   fread   reg   class   地方   

原文地址:https://www.cnblogs.com/zZh-Brim/p/9117772.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!