鼎纹【NOIP2016提高A组模拟9.7】

题目

鼎纹【NOIP2016提高A组模拟9.7】_第1张图片
样例输入:
鼎纹【NOIP2016提高A组模拟9.7】_第2张图片
2
3 4 4 2
1100
0110
1100
10
01
10
00
2 2 2 2
11
11
01
10

样例输出:
这里写图片描述
YES
NO

数据范围:
这里写图片描述


剖解题目

给你两个01矩阵AB,要求用B来印出A,其中B的1部分不可以印在空处且只能对A的某一处按下1次,问A是否能被A印出来。


思路

很明显,这道题是一道水题,因为可以发现只和1的位置有关系,所以只需要把1的位置记录下来即可。
然而我比赛的时候因为处理出现小问题就GG了QwQ.


解法

如上。


代码

#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)

using namespace std;

const int maxn=1005;
int num[maxn*maxn][2],tot1,a[maxn*maxn][2],tot2,map[maxn][maxn];
char ch[maxn];

int main()
{
    //freopen("T.in","r",stdin);
    int T;
    scanf("%d",&T);
    fo(oo,1,T){
        int n,m,x,y;
        scanf("%d%d%d%d",&n,&m,&x,&y);
        tot1=0; tot2=0;
        int t1=0,t2=0;
        fo(i,1,n){
            scanf("%s",&ch);
            fo(j,0,strlen(ch)-1)
            if (ch[j]=='1') {
                a[++tot1][0]=i;
                a[tot1][1]=j+1;
                map[i][j+1]=1;
                ++t1;
            }
            else map[i][j+1]=0;
        }
        fo(i,1,x){
            scanf("%s",&ch);
            fo(j,0,strlen(ch)-1) 
            if (ch[j]=='1') {
                num[++tot2][0]=i;
                num[tot2][1]=j+1;
                ++t2;
            }
        }
        if (t1%t2!=0) {
            printf("NO\n");
            continue;
        }
        bool b=true;
        fo(i,1,tot1)
        if (map[a[i][0]][a[i][1]]!=2){
            int xx=a[i][0]-num[1][0],yy=a[i][1]-num[1][1];
            fo(j,1,tot2){
                int nx=num[j][0]+xx,ny=num[j][1]+yy;
                if (nx<1||nx>n||ny<1||ny>m) {
                    b=false;
                    break;
                }
                if (map[nx][ny]==2) b=false;
                else if (map[nx][ny]) map[nx][ny]++;
                else b=false;
                if (!b) break;
            }
            if (!b) break;
            t1-=t2;
            if (!t1) break;
        }
        if (b) printf("YES\n"); else printf("NO\n");
    }
}

鼎纹【NOIP2016提高A组模拟9.7】_第3张图片

你可能感兴趣的:(信息技术,矩阵)