多连块是指由多个等大正方形边与边连接而成的平面连通图形。
– 维基百科
给一个大多连块和小多连块,你的任务是判断大多连块是否可以由两个这样的小多连块拼成。小多连块只能平移,不能旋转或者翻转。两个小多连块不得重叠。左下图是一个合法的拼法,但右边两幅图都非法。中间那幅图的问题在于其中一个小多连块旋转了,而右图更离谱:拼在一起的那两个多连块根本就不是那个给定的小多连块(给定的小多连块画在右下方)。
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"); } }