题意:给你几个拼图的碎片,问是否可以拼成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;
}