hdu 3111 DLX解数独

思路:裸的DLX解数独。关键是建图,感觉还不如写个dfs直接,DLX写这个的代码很烦。

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define Maxn 400010
#define Maxm 200010
#define LL __int64
#define Abs(x) ((x)>0?(x):(-x))
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define inf 100000
#define lowbit(x) (x&(-x))
#define clr(x,y) memset(x,y,sizeof(x))
#define Mod 1000000007
using namespace std;
int L[Maxn],R[Maxn],D[Maxn],U[Maxn],S[Maxn],C[Maxn],X[Maxn],Q[Maxn],H[1010],id;
int g[10][10];
void init(int m)
{
    int i;
    for(i=0;i<=m;i++){
        D[i]=U[i]=i;
        L[i+1]=i;
        R[i]=i+1;
        S[i]=0;
    }
    R[m]=0;
    id=m+1;
    clr(H,-1);
}
void ins(int r,int c)
{
    D[id]=D[c];
    U[id]=c;
    U[D[c]]=id;
    D[c]=id;
    S[c]++;
    if(H[r]<0)
        H[r]=L[id]=R[id]=id;
    else{
        L[id]=H[r];
        R[id]=R[H[r]];
        L[R[H[r]]]=id;
        R[H[r]]=id;
    }
    C[id]=c;
    X[id++]=r;
}
void Remove(int c)
{
    int i,j;
    R[L[c]]=R[c];
    L[R[c]]=L[c];
    for(i=D[c];i!=c;i=D[i]){
        for(j=R[i];j!=i;j=R[j]){
            D[U[j]]=D[j];
            U[D[j]]=U[j];
            S[C[j]]--;
        }
    }
}
void Resume(int c)
{
    int i,j;
    R[L[c]]=c;
    L[R[c]]=c;
    for(i=D[c];i!=c;i=D[i]){
        for(j=R[i];j!=i;j=R[j]){
            U[D[j]]=j;
            D[U[j]]=j;
            S[C[j]]++;
        }
    }
}
bool dfs(int k)
{
    int i,j,c,temp;
    if(R[0]==0){
        for(i=0;i<k;i++){
            int r,k;
            temp=X[Q[i]];
            k=temp%9;
            if(!k) k=9;
            c=(temp%81)/9;
            if(temp%81==0) c=9;
            if(temp%81%9) c++;
            r=temp/81;
            if(temp%81) r++;
            g[r][c]=k;
        }
        return true;
    }
    temp=inf;
    for(i=R[0];i;i=R[i]){
        if(S[i]<temp){
            temp=S[i];
            c=i;
        }
    }
    Remove(c);
    for(i=D[c];i!=c;i=D[i]){
        Q[k]=i;
        for(j=R[i];j!=i;j=R[j])
            Remove(C[j]);
        if(dfs(k+1))
            return true;
        for(j=L[i];j!=i;j=L[j])
            Resume(C[j]);
    }

    Resume(c);
    return false;
}
void build()
{
    int i,j,k,b,r,c;
    init(324);
    for(i=1;i<=9;i++){
        for(j=1;j<=9;j++){
            if(g[i][j]){
                r=(i-1)*81+(j-1)*9+g[i][j];
                c=(i-1)*9+g[i][j];
                ins(r,c);
                c=81+(j-1)*9+g[i][j];
                ins(r,c);
                c=162+(i-1)*9+j;
                ins(r,c);
                c=81*3+(((i-1)/3)*3+(j+2)/3-1)*9+g[i][j];
                ins(r,c);
                continue;
            }
            for(k=1;k<=9;k++){
                r=(i-1)*81+(j-1)*9+k;
                c=(i-1)*9+k;
                ins(r,c);
                c=81+(j-1)*9+k;
                ins(r,c);
                c=162+(i-1)*9+j;
                ins(r,c);
                c=81*3+(((i-1)/3)*3+(j+2)/3-1)*9+k;
                ins(r,c);
            }
        }
    }
}
int main()
{
    int t,i,j,f=0;
    char str[20];
    scanf("%d",&t);
    while(t--){
        clr(g,0);
        for(i=1;i<=9;i++){
            scanf("%s",str);
            for(j=0;j<9;j++){
                if(str[j]!='?')
                    g[i][j+1]=str[j]-'0';
            }
        }
        if(t)
        scanf("%s",str);
        build();
        if(f)
            printf("---\n");
        f=1;
        if(!dfs(0)){
            printf("impossible\n");
            continue;
        }
        for(i=1;i<=9;i++){
            for(j=1;j<=9;j++){
                printf("%d",g[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}

 

posted @ 2013-09-12 19:16  fangguo  阅读(244)  评论(0编辑  收藏  举报