多连块拼图

给一个大多连块和小多连块,你的任务是判断大多连块是否可以由两个这样的小多连块拼成。小多连块只能平移,不能旋转或者翻转。两个小多连块不得重叠。左下图是一个合法的拼法,但右边两幅图都非法。中间那幅图的问题在于其中一个小多连块旋转了,而右图更离谱:拼在一起的那两个多连块根本就不是那个给定的小多连块(给定的小多连块画在右下方)。

Input

输入最多包含20组测试数据。每组数据第一行为两个整数n和m(1<=m<=n<=10)。以下n行描述大多连块,其中每行恰好包含n个字符*或者.,其中*表示属于多连块,.表示不属于。以下m行为小多连块,格式同大多连块。输入保证是合法的多连块(注意,多连块至少包含一个正方形)。输入结束标志为n=m=0。

Output

对于每组测试数据,如果可以拼成,输出1,否则输出0。

Sample Input

4 3
.**.
****
.**.
....
**.
.**
...
3 3
***
*.*
***
*..
*..
**.
4 2
****
....
....
....
*.
*.
0 0

Sample Output

1
0
0

分析:应该算是模拟题,对小多连块进行分析,找到第一个出现*的位置记录下来,然后找到大多连块第一个出现*的位置,依据小多连块的*逐步枚举,同时消除在大多连块中相对应的*,如果没有*,则说明不能实现拼图。当消除一遍*后,如果大多连块不全为. (即还存在*),则继续下一轮扫描消除,知道不存在*为止。

代码:
#include<iostream>
#include<stdio.h>
using namespace std;
char a1[10][10],a2[10][10];
int n,m,i,j,x1,y1,x2,y2;
void show_a1()//显示消除过程
{
    printf("a1:\n");
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
            printf("%c",a1[i][j]);
        printf("\n");
    }
}
void a1_get_first()//得到a1数组第一个出现*的位置
{
    bool temp=true;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            if(a1[i][j]=='*')
            {
                x1=i;
                y1=j;
                temp=false;
                break;
            }
        }
        if(!temp)
            break;
    }
}
void a2_get_first()//得到a2数组第一个出现*的位置
{
    bool temp=true;
    for(i=0;i<m;i++)
    {
        for(j=0;j<m;j++)
        {
            if(a2[i][j]=='*')
            {
                x2=i;
                y2=j;
                temp=false;
                break;
            }
        }
        if(!temp)
            break;
    }
}
bool is_ok()//判断是否将所有*消除完成
{
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            if(a1[i][j]=='*')
                return false;
    return true;
}
int handle()//处理过程
{
    a2_get_first();
    while(!is_ok())
    {
        a1_get_first();
        for(i=x2;i<m;i++)
            for(j=0;j<m;j++)
                if(a2[i][j]=='*')//按照a2中出现的*逐个消除a1中的*
                {
                    if(a1[x1+i-x2][y1+j-y2]=='*')
                        a1[x1+i-x2][y1+j-y2]='.';
                    else//a2中某位置出现*而a1中未出现则一定会消除不干净
                        return 0;
                }
        //show_a1();
    }
    return 1;
}
int main()
{
    while(scanf("%d%d",&n,&m)&&n)
    {
        for(i=0;i<n;i++)
            scanf("%s",&a1[i]);
        for(i=0;i<m;i++)
            scanf("%s",&a2[i]);
        printf("%d\n",handle());
    }
    return 0;
}




版权声明:本文为xing634325131原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。