BZOJ 2469 [中山市选2010]简单数谜
一道搜索题
比较基础(hh,下午出这题我就玩完了)
要加剪枝,把自己能想到的剪枝都加上去
#include <stdio.h> int read(){ int x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int min(int x,int y){ return x>y?y:x; } int cal(int x){ int res=1; while(!(x&1)) x>>=1,res++; return res; } int a[10][10]; int b[10],c[10]; int hhd[10][10]; int num[10],cnt[10]; int n,m,ans; void print(){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) printf("%d ",hhd[i][j]); puts(""); } } void dfs(int x,int y){ if(x==n+1){ for(int i=1;i<=m;i++) if(c[i]) return ; ans++; return ; } if(y==m+1){ if(b[x]) return ; dfs(x+1,1); return ; } if(a[x][y]!=-1){ dfs(x,y+1); return; } int i; for(i=num[x]&cnt[y];i;i-=i&(-i)){ int id=i&(-i); int kk=cal(id); if(kk>b[x]||kk>c[y]) return ; b[x]-=kk;c[y]-=kk; num[x]-=id;cnt[y]-=id; if(ans==0) hhd[x][y]=kk; dfs(x,y+1); b[x]+=kk;c[y]+=kk; num[x]+=id;cnt[y]+=id; if(ans>1) return ; } } int main(){ int T=read(),i,j; while(T--){ n=read(),m=read();ans=0; for(i=1;i<=n;i++) b[i]=read(),num[i]=(1<<9)-1; for(j=1;j<=m;j++) c[j]=read(),cnt[j]=(1<<9)-1; for(i=1;i<=n;i++) for(j=1;j<=m;j++){ a[i][j]=read()-1; if(a[i][j]!=-1) num[i]^=(1<<a[i][j]),cnt[j]^=(1<<a[i][j]),b[i]-=a[i][j]+1,c[j]-=a[i][j]+1,hhd[i][j]=a[i][j]+1; } dfs(1,1); if(ans>1) puts("Not unique."); else if(ans==0) puts("No answer."); else print(); } return 0; }