这题就是一个暴搜,剪枝都不需要,主要需要处理的就是怎样判断一个碎片能否放进去4*4的正方形里,
,其实这里也很简单就能处理,读题的时候读错了,以为碎片不用完能拼成正方形也可以,然而并不是,
每一片都要用,这样还从逻辑上减少了时间复杂度,更简单一些,改下就过了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<cmath>
#include<climits>
#include<vector>
#include<cfloat>
#include<queue>
#include<cctype>
#include<cstdlib>
#include<string>
#define LL long long
using namespace std;
struct node
{
int c,r;
int s[10][10];
}a[16];
int flag;
int n,m=0;
int re[10][10];
void dfs(int cur)
{
/* for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
cout<<re[i][j];
cout<<endl;
}
cout<<endl;*/
/*if(flag) return;
if(cur>n+1) return;
int ok=1;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(!re[i][j])
ok=0;
if(ok)
{
flag=1;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
cout<<re[i][j];
cout<<endl;
}
return;
}*/
if(cur==n+1)
{
flag=1;
return;
}
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(i+a[cur].c<=4&&j+a[cur].r<=4)
{
int ok1=1;
for(int x=i;x<i+a[cur].c;x++)
for(int y=j;y<j+a[cur].r;y++)
if(a[cur].s[x-i][y-j]&&re[x][y])
ok1=0;
if(ok1)
{
for(int x=i;x<i+a[cur].c;x++)
for(int y=j;y<j+a[cur].r;y++)
if(a[cur].s[x-i][y-j])
re[x][y]=cur;
dfs(cur+1);
if(flag)
return;
for(int x=i;x<i+a[cur].c;x++)
for(int y=j;y<j+a[cur].r;y++)
if(a[cur].s[x-i][y-j])
re[x][y]=0;
}
}
}
}
}
int main()
{
while(cin>>n&&n)
{
memset(re,0,sizeof(re));
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
cin>>a[i].c>>a[i].r;
for(int j=0;j<a[i].c;j++)
{
string ss;
cin>>ss;
for(int k=0;k<a[i].r;k++)
a[i].s[j][k]=ss[k]-'0';
}
}
/* for(int i=1;i<=n;i++)
{
for(int j=0;j<a[i].c;j++)
{
for(int k=0;k<a[i].r;k++)
cout<<a[i].s[j][k];
cout<<endl;
}
}*/
flag=0;
if(m++) cout<<endl;
dfs(1);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(re[i][j]==0) flag=0;
if(!flag)
cout<<"No solution possible"<<endl;
else
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
cout<<re[i][j];
cout<<endl;
}
}
}
return 0;
}