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;
}

  

posted @ 2018-11-14 10:27  古城独钓  阅读(174)  评论(0编辑  收藏  举报