hust NENU Summer Training 2014 #2 D - Polyomino Decomposer

本文介绍了一种解决特定编程问题的方法,通过利用给定的两个图来填充另一个图,确保不进行旋转和覆盖操作。详细解释了算法流程,包括如何计算距离并应用填充逻辑。

这是一道比较水的题,只要理解了题意就行了。

题意:给你一个原有的图1,‘*’表示1,'.'表示空,再给你一个图2,现在让你用2个图2来填充图1,不能旋转和覆盖。如果可以就输出1,不行就输出0;

思路:将图2的点距离第一个“*”的x和y的距离算出来,保存在数组num_x和num_y中。然后循环两次,最后判断是否还有就行了。

代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
char str1[16][16];
char str2[16][16];
int num1[16][16];
int num_x[110];
int num_y[110];
int n,m;
int k=0;
int check() {
    for(int i=0; i<n; i++) {
        for(int j=0; j<n; j++) {
            if(num1[i][j]==1) {
                return 0;
            }
        }
    }
    return 1;
}


int solve() {
    for(int s=0; s<2; s++) {
        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                if(num1[i][j]==1) {
                    for(int t=0; t<k; t++) {
                        if(num1[i+num_x[t]][j+num_y[t]]==1) {
                            num1[i+num_x[t]][j+num_y[t]]=0;
                        } else {
                            return 0;
                        }
                    }
                }
            }
        }
    }
    return check();
}


int main() {


    while(cin>>n>>m) {
        if(n==0&&m==0) {
            break;
        }
        for(int i=0; i<n; i++) {
            cin>>str1[i];
        }
        memset(num1,0,sizeof(num1));
        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                if(str1[i][j]=='*') {
                    num1[i][j]=1;
                }
            }
        }


        for(int i=0; i<m; i++) {
            cin>>str2[i];
        }


        int flagi=0;
        int flagj=0;
        int flag=0;
        for(int i=0; i<m; i++) {
            for(int j=0; j<m; j++) {
                if(str2[i][j]=='*') {
                    flagi=i;
                    flagj=j;
                    flag=1;
                    break;
                }
            }
            if(flag) {
                break;
            }
        }
        num_x[0]=0;
        num_y[0]=0;
        k=1;
        for(int i=flagi; i<m; i++) {
            for(int j=0; j<m; j++) {
                if(i==flagi&&j==flagj) {
                    continue;
                }
                if(str2[i][j]=='*') {
                    num_x[k]=i-flagi;
                    num_y[k++]=j-flagj;
                }
            }
        }
        int s=solve();
        if(s) {
            printf("1\n");
        } else {
            printf("0\n");
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值