湖南省第七届大学生计算机程序设计竞赛多连块拼图
题目C 多连块拼图
多连块是指由多个等大正方形边与边连接而成的平面连通图形。
维基百科
给一个大多连块和小多连块,你的任务是判断大多连块是否可以由两个这样的小多连块拼成。小多连块只
能平移,不能旋转或者翻转。两个小多连块不得重叠。左下图是一个合法的拼法,但右边两幅图都非法。中间
那幅图的问题在于其中一个小多连块旋转了,而右图更离谱:拼在一起的那两个多连块根本就不是那个给定的
小多连块(给定的小多连块画在右下方)。
输入
输入最多包含20组测试数据。每组数据第一行为两个整数n和m(1<m<=n<=10)。以下n行描述大多连块,其中每行恰好包含n个字符*或者.,其*表示属于多连块,.表示不属于。以下m行为小多连块,格式同大多连块。输入保证是合法的多连块(注意,多连块至少包含一个正方形)。输入结束标志为n=m=0。
输出
对于每组测试数据,如果可以拼成,输1,否则输出0。
样例输入
样例输出
4 3
.**.
****
.**.
....
**.
.**
...
3 3
***
*.*
***
*..
*..
**.
4 2
****
....
....
....
*.
*.
0 0
1
0
0
注意:题意判断大多连块是否可以由两个一样的小多连块拼成
思路:用小模块直接在大模块上进行对比
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; char a[15][15],b[15][15]; int ax=0,ay=0,bx=0,by=0; int n,m,mark; void start() { mark=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(a[i][j]=='*') { ax=i; ay=j; mark=1; break; } } if(mark==1) break; } } int out() { for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(a[i][j]=='*') return 0; } return 1; } int pd() { int t=0; while(t<2) { start(); for(int i=bx;i<m;i++) { for(int j=0;j<m;j++) { if(b[i][j]=='*') { if(a[ax+i-bx][ay+j-by]=='*') a[ax+i-bx][ay+j-by]='.'; else return 0; } } } t++; } if(out()) return 1; else return 0; } int main() { while(~scanf("%d%d",&n,&m)) { int tt=0,ttt=0; if(n==0&&m==0) break; int mark1=0; for(int i=0;i<n;i++) scanf("%s",&a[i]); for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(a[i][j]=='*') tt++; } for(int i=0;i<m;i++) scanf("%s",&b[i]); for(int i=0;i<m;i++) for(int j=0;j<m;j++) { if(b[i][j]=='*') ttt++; if(b[i][j]=='*'&&mark1==0) { bx=i; by=j; mark1=1; } } if(2*ttt!=tt) printf("0\n"); else printf("%d\n",pd()); } return 0; }