多连块拼图

来源:互联网 发布:win mac 文件共享 编辑:程序博客网 时间:2024/04/28 02:30

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

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;}



原创粉丝点击