题目大意:有个n*m的格子图,要求'x'点要被染成黑色
有个a*b的印章,'x'是可以染色的印章上的点。
要求用印章去染色格子
(1)印章不可以旋转。
(2)不能把墨水印到纸外面。
(3)纸上的同一个格子不可以印多次。
题解:模拟
从题目中可以看出,一定要让印章的左上角对应目前n*m方
格中未染色的左上角。因为要求不能重复染色,可以每染完
一个格子就把它赋值为0.(待染色为1)。
开始纯模拟,没有任何优化的代码。
加了个读入优化还是T了两个点,3000ms+
#include<iostream> #include<cstdio> #include<cstring> #define N 1022 using namespace std; int n,m,a,b,fa,fb,cnt,q; int map[N][N],yz[N][N]; char s[N]; inline int read(int &x){ char ch=getchar();x=0;int f=1; for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0'; x=x*f; } void init(){ memset(map,0,sizeof(map)); memset(yz,0,sizeof(yz)); cnt=0;fa=0;fb=0; } bool check(int x,int y){ int xx=x-fa,yy=y-fb; for(int i=1;i<=a;i++){ for(int j=1;j<=b;j++){ if(yz[i][j]==0)continue; int rx=xx+i,ry=yy+j; if(rx<0||ry<0||rx>n||ry>m||map[rx][ry]==0)return false; map[rx][ry]=0;cnt--; } } return true; } int main(){ scanf("%d",&q); while(q--){ init();bool flag=false; // scanf("%d%d%d%d",&n,&m,&a,&b); // n=read();m=read();a=read();b=read(); read(n);read(m);read(a);read(b); for(int i=1;i<=n;i++){ scanf("%s",s+1); for(int j=1;j<=m;j++) if(s[j]=='x')map[i][j]=1,cnt++; } for(int i=1;i<=a;i++){ scanf("%s",s+1); for(int j=1;j<=b;j++){ if(s[j]=='.')continue; if(!fa&&!fb)fa=i,fb=j; yz[i][j]=1; } } for(register int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(map[i][j]){ if(check(i,j)==0){ printf("NIE\n"); flag=true;break; } if(cnt==0){ printf("TAK\n"); flag=true;break; } } } if(flag)break; } } return 0; }