HDU 5613 Baby Ming and Binary image
因为第一行和最后一行都是0,我们只需枚举最左边或最右边一列的01情况,即可得到整张表
然后再检验表是否符合要求
#include<cstdio> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<list> #include<algorithm> using namespace std; int T; int n,m; int a[15][150],ans[15][150],pri[15][150]; int b[15]; int num; int Y; bool f(int x,int y) { if(x>=0&&x<n&&y>=0&&y<m) return 1; return 0; } int getSum(int i,int j) { int res=0; if(f(i-1,j-1)) res=res+ans[i-1][j-1]; if(f(i-1,j)) res=res+ans[i-1][j]; if(f(i-1,j+1)) res=res+ans[i-1][j+1]; if(f(i,j-1)) res=res+ans[i][j-1]; if(f(i,j)) res=res+ans[i][j]; if(f(i,j+1)) res=res+ans[i][j+1]; if(f(i+1,j-1)) res=res+ans[i+1][j-1]; if(f(i+1,j)) res=res+ans[i+1][j]; if(f(i+1,j+1)) res=res+ans[i+1][j+1]; return res; } void dfs(int tot) { if(tot==n-2) { bool fail=0; //填表 memset(ans,0,sizeof ans); for(int i=0;i<m;i++) ans[0][i]=0,ans[n-1][i]=0; for(int i=1;i<=n-2;i++) ans[i][0]=b[i-1]; for(int j=1;j<=m-1;j++) for(int i=1;i<=n-2;i++) ans[i][j]=a[i-1][j-1]-getSum(i-1,j-1); //填完检查 for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(a[i][j]!=getSum(i,j)) fail=1; if(ans[i][j]!=1&&ans[i][j]!=0) fail=1; } } if(fail==0) { num++; if(num==2) Y=1; else if(num==1) { for(int i=0;i<n;i++) for(int j=0;j<m;j++) pri[i][j]=ans[i][j]; } } return; } b[tot]=0; dfs(tot+1); if(Y) return; b[tot]=1; dfs(tot+1); if(Y) return; } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) scanf("%d",&a[i][j]); if(m==0) { printf("Impossible\n"); continue; } num=0;Y=0; dfs(0); if(Y==1) printf("Multiple\n"); else if(num==1) { for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { printf("%d",pri[i][j]); if(j<m-1) printf(" "); else printf("\n"); } } } else printf("Impossible\n"); } return 0; }