D-多连块拼图

多连块是指由多个等大正方形边与边连接而成的平面连通图形。
– 维基百科

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

分析:
因为题中说不能旋转,所以枚举第一块和第二块的位置即可;
代码:

#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;
const int N = 10 + 5;

char goal[N][N];
char mat[N][N],st[N][N],tmp[N][N];
struct node{
    int x,y;
}Node[105];
int cnt,n,m;
void To_left_top(){
    int dx=0,dy=0,i,j;
    for(i=0;i<m;i++){
        for(j=0;j<m;j++) if(st[i][j]=='*') break;
        if(j == m) dx--;
        else break;
    }
    for(j=0;j<m;j++){
        for(i=0;i<m;i++) if(st[i][j]=='*') break;
        if(i == m) dy--;
        else break;
    }
    for(int i=0;i<cnt;i++) Node[i].x+=dx,Node[i].y+=dy;
}
void print(){
   for(int i=0;i<cnt;i++){
            mat[Node[i].x][Node[i].y] = '*';
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<m;j++){
                printf("%c",mat[i][j]);
                if(j==m-1) printf("
");
            }
        }
}
bool match(){
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        if(goal[i][j]!=tmp[i][j]) return false;
    return true;
}
bool next_add(int x,int y){
    memcpy(tmp,mat,sizeof(mat));
    for(int i=0;i<cnt;i++){
        int newx = x + Node[i].x;
        int newy = y + Node[i].y;
        if(newx>=n || newy>=n || tmp[newx][newy]=='*') return false;
        tmp[newx][newy] = '*';
    }
    if(match()) return true;
    else return false;
}
bool add(int x,int y){
    memset(mat,'.',sizeof(mat));
    for(int i=0;i<cnt;i++){
        int newx = Node[i].x + x;
        int newy = Node[i].y + y;
        if(newx>=n || newy>= n) return false;
        mat[newx][newy] = '*';
    }
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++){
        if(!next_add(i,j)) continue;
        else return true;
    }
    return false;
}
bool solve(){
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++){
        if(!add(i,j)) continue;
        else return true;
    }
    return false;
}
int main(){
    while(scanf("%d %d",&n,&m)==2 &&(n||m)){
        cnt = 0;
        for(int i=0;i<n;i++) scanf("%s",goal[i]);
        for(int i=0;i<m;i++){
            scanf("%s",st[i]);
            for(int j=0;j<m;j++) if(st[i][j]=='*') Node[cnt].x = i,Node[cnt++].y = j;
        }
        To_left_top();
        printf("%s
",solve()?"1":"0");
    }
}
原文地址:https://www.cnblogs.com/Pretty9/p/7347691.html