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;

}

 

你可能感兴趣的:(HDU)