您的位置:首页 > 其它

BZOJ 3750

2016-02-23 23:35 330 查看
题意:一张n*m的方格纸,有些格子需要印成黑色,剩下的格子需要保留白色。

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

(1)印章不可以旋转。

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

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

很显然的想法,每次染色肯定要用印章的左上角对准当然位置最靠前的未染色的黑点。这样就像链表一样从第一个开始一直染下去,暴力检验。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=1000*1000+10;
const int maxlen=1000+10;
char ch[maxn];
int cnt1,cnt2,is[maxlen][maxlen],del[maxlen][maxlen],n,m,a,b,T,dx[maxn],dy[maxn],px[maxn],py[maxn];
bool check(int p)
{
del[px[p]][py[p]]=1;
int hx=px[p],hy=py[p];
for(int i=1;i<=cnt2;i++)
{
hx+=dx[i];hy+=dy[i];
if(hx<1||hx>n||hy<1||hy>m) return 0;
if(!is[hx][hy]) return 0;
if(del[hx][hy]) return 0;
del[hx][hy]=1;

}
return 1;
}
int main()
{
//freopen("3750.in","r",stdin);
//freopen("3750.out","w",stdout);
scanf("%d",&T);
while(T--)
{
int flag=1,nx,ny;
memset(del,0,sizeof(del));cnt1=cnt2=0;
scanf("%d%d%d%d",&n,&m,&a,&b);
for(int i=1;i<=n;i++)
{
scanf("%s",&ch);
for(int j=0;j<m;j++)
if(ch[j]=='x')
{
is[i][j+1]=1;
del[i][j+1]=0;
cnt1++;px[cnt1]=i;py[cnt1]=j+1;
}
else is[i][j+1]=0;
}
for(int i=1;i<=a;i++)
{
scanf("%s",&ch);
for(int j=0;j<b;j++)
if(ch[j]=='x')
{
cnt2++;
if(cnt2==1)
{
nx=i;
ny=j+1;
}
else
{
dx[cnt2-1]=i-nx;dy[cnt2-1]=j+1-ny;
nx=i;ny=j+1;
}
}
}
cnt2--;
for(int i=1;i<=cnt1;i++)
if(!del[px[i]][py[i]])
{
flag=check(i);
if(!flag) break;
}
if(flag) puts("TAK");
else puts("NIE");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: