传送门:hdu5613
题解
特殊性质:第一行和最后一行为0。 n ≤ 12 n\leq 12 n≤12。
发现复杂度刚好是可以
T
2
n
−
2
n
m
T2^{n-2}nm
T2n−2nm的。
于是暴力枚举第一列,后面的都可以递推得到,答案唯一,判断一下即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=(1<<12)+10;
int tk,n,m,cot;
int a[12][100],b[12][100],c[12][100],d[12][100];
const int dx[10]={-1,-1,-1,0,0,0,1,1,1};
const int dy[10]={-1,0,1,-1,0,1,-1,0,1};
inline bool upp(int x,int y)
{
int i,ix,iy;
for(i=0;i<9;++i){
ix=x+dx[i];iy=y+dy[i];
if(ix<0 || ix>=n || iy<0 || iy>=m) continue;
if((--c[ix][iy])<0) return true;
}
return false;
}
void ck(int s)
{
int i,j;
memset(b,0,sizeof(b));
memcpy(c,a,sizeof(c));
for(i=0;i<n-2;++i) if((s>>i)&1){
b[i+1][0]=1;
if(upp(i+1,0)) return;
}
for(j=1;j<m;++j)
for(i=1;i+1<n;++i)
if(c[i-1][j-1]>0){
b[i][j]=1;
if(upp(i,j)) return;
}
for(i=0;i<n;++i)
for(j=0;j<m;++j)
if(c[i][j]!=0) return;
cot++;if(cot>1) return;
memcpy(d,b,sizeof(d));
}
int main(){
int i,j;
for(scanf("%d",&tk);tk;--tk){
scanf("%d%d",&n,&m);cot=0;
for(i=0;i<n;++i)
for(j=0;j<m;++j)
scanf("%d",&a[i][j]);
for(i=(1<<(n-2))-1;i>=0;--i) ck(i);
if(!cot) puts("Impossible");
else if(cot>1) puts("Multiple");
else{
for(i=0;i<n;++i){
for(j=0;j+1<m;++j)
printf("%d ",d[i][j]);
printf("%d\n",d[i][m-1]);
}
}
}
return 0;
}