Description
Polyomino Composer |
A polyomino is a plane geometric figure formed by joining one or more equal squares edge to edge.- Wikipedia
Given a large polyomino and a small polyomino, your task is to determine whether you can compose the large one with two copies of the small one. The polyominoes can be translated, but not flipped or rotated. The two pieces should not overlap. The leftmost picture below is a correct way of composing the large polyomino, but the right two pictures are not. In the middle picture, one of the pieces was rotated. In the rightmost picture, both pieces are exactly identical, but they're both rotated from the original piece (shown in the lower-right part of the picture).
4 3 .**. **** .**. .... **. .** ... 3 3 *** *.* *** *.. *.. **. 4 2 **** .... .... .... *. *. 0 0
1 0 0
The Seventh Hunan Collegiate Programming Contest
Problemsetter: Rujia Liu, Special Thanks: Yiming Li & Jane Alam Jan
这个题目的意思就是给你两图形,问你用两张第二种图能否组成第一张第一种张图,方向不能改变。
看到这个题,我首先想到的就是枚举(n-height)*(n-width)个点,因为m和n都很小,就枚举法了,由于我水平很水,调了好久好久。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,m; bool cover(char a[12][12],int px,int py,char b[12][12],int sx,int sy) { //功能:把子图b从(sx,sy)到(m,m)中的‘*’贴到a图中。 for(int i=sx,j=px;i<m;i++,j++) { for(int k=sy,l=py;k<m;k++,l++) { //如果能赋值就赋值 if(b[i][k]=='*'&&a[j][l]=='.') a[j][l]=b[i][k]; else if(b[i][k]=='*'&&a[j][l]=='*') return false; //如果不能赋值则返回cover失败。 } } return true; } void init(char a[12][12]) {//把图初始化为全是‘.’的图。 for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { a[i][j]='.'; } a[i][n]='\0'; } } void copy(char a[12][12],char b[12][12]) {//如命名 for(int i=0; i<n; i++) strcpy(a[i],b[i]); } bool issame(const char a[12][12],const char b[12][12]) {//判断两图是否相同。 for(int i=0; i<n; i++) if(strcmp(a[i],b[i])!=0) return false; return true; } int main() { //freopen("in.txt","r",stdin); char big[12][12],part[12][12]; char blank[12][12],tmp[12][12]; int minx,miny,maxx,maxy; bool flag; while(scanf("%d%d",&n,&m),m||n) { minx=m,miny=m,flag=0; maxx=0,maxy=0; for(int i=0; i<n; i++) scanf("%s",big[i]); for(int j=0; j<m; j++) scanf("%s",part[j]); for(int i=0; i<m; i++) for(int j=0; j<m; j++) { if(part[i][j]=='*') { if(minx>i)minx=i;if(miny>j)miny=j; if(maxx<i)maxx=i;if(maxy<j)maxy=j; } } int height=maxx-minx,width=maxy-miny; for(int i=0; i<n-height; i++) { for(int j=0; j<n-width; j++) { init(blank); cover(blank,i,j,part,minx,miny); for(int l=0; l<n-height; l++) { for(int k=0; k<n-width; k++) { copy(tmp,blank); if(tmp[l][k]=='.'&&cover(tmp,l,k,part,minx,miny)) { if(issame(big,tmp)) { flag=1; i=100,j=100,l=100,k=100; //这里给i,j,l,k赋值是用来退出多重循环用的。 } } } } } } printf("%d\n",flag); } return 0; }