• POJ 3074 Sudoku(Dancing Links)


    Dancing Links是使用双向循环十字链表的数据结构通过dfs来实现解决精确覆盖问题的强有力的武器。

    而数独问题可以转化为精确覆盖问题。

    通过将每个限制转化为列。每个决策转化为行。

    建模型:
    行数为9*9*9,数独中,第i行j列放数字k的状态存储在图中第(i*9+j)*9+k行中
    列数为9*9+9*9+9*9+9*9,

    其中第一个9*9代表第i格是否已填满,
    用第二个9*9确保每行的数字唯一且均出现一次
    第三个9*9确保每列的数字唯一且出现一次
    第四个9*9确保每宫的数字唯一出现1次

    # include <cstdio>
    # include <cstring>
    # include <cstdlib>
    # include <iostream>
    # include <vector>
    # include <queue>
    # include <stack>
    # include <map>
    # include <set>
    # include <cmath>
    # include <algorithm>
    using namespace std;
    # define lowbit(x) ((x)&(-x))
    # define pi 3.1415926535
    # define eps 1e-4
    # define MOD 1000000007
    # define INF 1000000000
    # define mem(a,b) memset(a,b,sizeof(a))
    # define FOR(i,a,n) for(int i=a; i<=n; ++i)
    # define FO(i,a,n) for(int i=a; i<n; ++i)
    # define bug puts("H");
    # define lch p<<1,l,mid
    # define rch p<<1|1,mid+1,r
    # define mp make_pair
    # define pb push_back
    typedef pair<int,int> PII;
    typedef vector<int> VI;
    # pragma comment(linker, "/STACK:1024000000,1024000000")
    typedef long long LL;
    inline int Scan() {
        int x=0,f=1;char 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;
    }
    void Out(int a) {
        if(a<0) {putchar('-'); a=-a;}
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=9;
    //Code begin...
    
    const int MaxN=N*N*N+10, MaxM=N*N*4+10, maxnode=MaxN*4+MaxM+10;
    char g[MaxN];
    struct DLX{
        int n, m, size;
        int U[maxnode], D[maxnode], R[maxnode], L[maxnode], Row[maxnode], Col[maxnode];
        int H[MaxN], S[MaxM], ansd, ans[MaxN];
        void init(int _n, int _m){
            n=_n; m=_m;
            FOR(i,0,m) S[i]=0, U[i]=D[i]=i, L[i]=i-1, R[i]=i+1;
            R[m]=0; L[0]=m; size=m;
            FOR(i,1,n) H[i]=-1;
        }
        void Link(int r, int c){
            ++S[Col[++size]=c]; Row[size]=r; D[size]=D[c]; U[D[c]]=size; U[size]=c; D[c]=size;
            if (H[r]<0) H[r]=L[size]=R[size]=size;
            else R[size]=R[H[r]], L[R[H[r]]]=size, L[size]=H[r], R[H[r]]=size;
        }
        void remove(int c){
            L[R[c]]=L[c]; R[L[c]]=R[c];
            for (int i=D[c]; i!=c; i=D[i]) for (int j=R[i]; j!=i; j=R[j]) U[D[j]]=U[j], D[U[j]]=D[j], --S[Col[j]];
        }
        void resume(int c){
            for (int i=U[c]; i!=c; i=U[i]) for (int j=L[i]; j!=i; j=L[j]) ++S[Col[U[D[j]]=D[U[j]]=j]];
            L[R[c]]=R[L[c]]=c;
        }
        bool Dance(int d){
            if (R[0]==0) {
                FO(i,0,d) g[(ans[i]-1)/9]=(ans[i]-1)%9+'1';
                FO(i,0,N*N) printf("%c",g[i]);
                printf("
    ");
                return true;
            }
            int c=R[0];
            for (int i=R[0]; i!=0; i=R[i]) if (S[i]<S[c]) c=i;
            remove(c);
            for (int i=D[c]; i!=c; i=D[i]) {
                ans[d]=Row[i];
                for (int j=R[i]; j!=i; j=R[j]) remove(Col[j]);
                if (Dance(d+1)) return true;
                for (int j=L[i]; j!=i; j=L[j]) resume(Col[j]);
            }
            resume(c);
            return false;
        }
    }dlx;
    void place(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k){
        r=(i*N+j)*N+k; c1=i*N+j+1; c2=N*N+i*N+k;
        c3=N*N*2+j*N+k; c4=N*N*3+((i/3)*3+(j/3))*N+k;
    }
    int main ()
    {
        while (~scanf("%s",g)&&strcmp(g,"end")) {
            dlx.init(N*N*N,N*N*4);
            int r, c1, c2, c3, c4;
            FO(i,0,N) FO(j,0,N) FOR(k,1,N) if (g[i*N+j]=='.'||g[i*N+j]=='0'+k) {
                place(r,c1,c2,c3,c4,i,j,k);
                dlx.Link(r,c1); dlx.Link(r,c2); dlx.Link(r,c3); dlx.Link(r,c4);
            }
            dlx.Dance(0);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    随笔 祝我快乐
    .NET设计模式单件模式(Singleton Pattern)
    随笔 缘分
    随笔 雨季
    数据库设计中的小经验
    一个字节造成的巨大性能差异——SQL Server存储结构
    随笔 淡淡的幸福
    用LINQ还是NHibernate?
    随笔 风筝
    FreeStyle Wishes
  • 原文地址:https://www.cnblogs.com/lishiyao/p/6709229.html
Copyright © 2020-2023  润新知