题意:给你几个拼图的碎片,问是否可以拼成4*4的正方形,我们从头(1,1)枚举每一个坐标,(注意会有超出4*4的情况,WA在这里),然后我们先判断放下这个碎片是否会冲突,如果不会的话,我们就记录这个碎片的方格数,最后,如果满足16的话,那么这种情况便是成立的,最后输出4*4 的每一个方格所代表的拼图
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int t,n,m; char map[10][10]; int vis[10]; int sign; struct node { char set[10][10]; int n,m; int num; }arr[20]; int judge(int cur,int x,int y) { for (int i = x; i < x + arr[cur].n; i++) for (int j = y; j < y + arr[cur].m; j++) if (map[i][j] != '0' && arr[cur].set[i-x][j-y] != '0') return 0; return 1; } void dfs(int x,int y,int cur,int num) { if (cur == t) { if (num == 16) sign = 1; return ; } if (y > 4) { if (x < 4) dfs(x+1,1,cur,num); return; } for (int i = 1; i <= t; i++) { if (!vis[i] && judge(i,x,y)) { vis[i] = 1; for (int j = x; j < x + arr[i].n; j++) for (int k = y; k < y + arr[i].m; k++) if (arr[i].set[j-x][k-y] == '1') map[j][k] = i - 1 + '1'; dfs(x,y+1,cur+1,num+arr[i].num); if (sign) return; vis[i] = 0; for (int j = x; j < x + arr[i].n; j++) for (int k = y; k < y + arr[i].m; k++) if (arr[i].set[j-x][k-y] != '0') map[j][k] = '0'; } } dfs(x,y+1,cur,num); // 不再这个位置放 } int main() { int cas = 0; while (scanf("%d",&t) != EOF && t) { if (cas == 0) cas = 1; else printf("\n"); memset(arr,0,sizeof(arr)); memset(vis,0,sizeof(vis)); memset(map,'1',sizeof(map)); for (int i = 1; i <= 4; i++) for (int j = 1; j <= 4; j++) map[i][j] = '0'; for (int i = 1; i <= t; i++) { scanf("%d%d",&n,&m); getchar(); arr[i].n = n,arr[i].m = m; for (int j = 0; j < n; j++) { gets(arr[i].set[j]); for (int k = 0; k < strlen(arr[i].set[j]); k++) if (arr[i].set[j][k] != '0') arr[i].num++; } } sign = 0; dfs(1,1,0,0); if (sign) { for (int i = 1; i <= 4; i++) { for (int j = 1; j <= 4; j++) printf("%c",map[i][j]); printf("\n"); } } else printf("No solution possible\n"); } return 0; }