• POJ2676 Sudoku 舞蹈链 DLX


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解

    题目(传送门)

    题意概括

    给出一个残缺的数独,求解。SPJ

    题解

    DLX  +  矩阵构建  (两个传送门)

    代码

    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int N=800,M=400,S=N*4+M;
    struct DLX{
        int n,m,cnt;
        int x[S],y[S],L[S],R[S],U[S],D[S];
        int C[M],anscnt,ans[N];
        void init(int c){
            memset(x,0,sizeof x);
            memset(y,0,sizeof y);
            memset(L,0,sizeof L);
            memset(R,0,sizeof R);
            memset(U,0,sizeof U);
            memset(D,0,sizeof D);
            memset(C,0,sizeof C);
            memset(ans,0,sizeof ans);
            anscnt=0;
            m=c;
            for (int i=0;i<=m;i++)
                L[i]=i-1,R[i]=i+1,U[i]=D[i]=i;
            L[0]=m,R[m]=0,cnt=m;
        }
        void link(int i,int j){
            cnt++;
            x[cnt]=i;
            y[cnt]=j;
            L[cnt]=cnt-1;
            R[cnt]=cnt+1;
            D[cnt]=j;
            D[U[j]]=cnt;
            U[cnt]=U[j];
            U[j]=cnt;
            C[j]++;
        }
        void Delete(int k){
            L[R[k]]=L[k];
            R[L[k]]=R[k];
            for (int i=D[k];i!=k;i=D[i])
                for (int j=R[i];j!=i;j=R[j]){
                    U[D[j]]=U[j];
                    D[U[j]]=D[j];
                    C[y[j]]--;
                }
        }
        void Reset(int k){
            L[R[k]]=k;
            R[L[k]]=k;
            for (int i=U[k];i!=k;i=U[i])
                for (int j=L[i];j!=i;j=L[j]){
                    U[D[j]]=j;
                    D[U[j]]=j;
                    C[y[j]]++;
                }
        }
        bool solve(){
            if (R[0]==0)
                return true;
            anscnt++;
            int k=R[0];
            for (int i=R[k];i!=0;i=R[i])
                if (C[i]<C[k])
                    k=i;
            Delete(k);
            for (int i=D[k];i!=k;i=D[i]){
                ans[anscnt]=x[i];
                for (int j=R[i];j!=i;j=R[j])
                    Delete(y[j]);
                if (solve())
                    return true;
                for (int j=L[i];j!=i;j=L[j])
                    Reset(y[j]);
            }
            Reset(k);
            anscnt--;
            return false;
        }
    }dlx;
    int T,a[15][15],x[800],y[800],z[800];
    char s[15];
    int hash(int a,int b,int c){
        return a*81+b*9+c+1;
    }
    int main(){
        scanf("%d",&T);
        while (T--){
            for (int i=1;i<=9;i++){
                scanf("%s",s+1);
                for (int j=1;j<=9;j++)
                    a[i][j]=s[j]-48;
            }
            dlx.init(9*9*4);
            int Row=0;
            for (int i=1;i<=9;i++)
                for (int j=1;j<=9;j++){
                    int st,en;
                    if (a[i][j]==0)
                        st=1,en=9;
                    else
                        st=en=a[i][j];
                    for (int k=st;k<=en;k++){
                        Row++;
                        x[Row]=i,y[Row]=j,z[Row]=k;
                        int first=dlx.cnt+1;
                        dlx.link(Row,hash(0,i-1,j-1));
                        dlx.link(Row,hash(1,i-1,k-1));
                        dlx.link(Row,hash(2,j-1,k-1));
                        dlx.link(Row,hash(3,((i-1)/3)*3+(j-1)/3,k-1));
                        dlx.L[first]=dlx.cnt;
                        dlx.R[dlx.cnt]=first;
                    }
                }
            bool found=dlx.solve();
            for (int i=1;i<=dlx.anscnt;i++)
                a[x[dlx.ans[i]]][y[dlx.ans[i]]]=z[dlx.ans[i]];
            for (int i=1;i<=9;puts(""),i++)
                for (int j=1;j<=9;j++)
                    printf("%d",a[i][j]);
        }
        return 0;
    }
  • 相关阅读:
    MPSOC之5——开发流程BOOT.BIN
    MPSOC之6——开发流程linux编译
    MPSOC之1——overview、开发板、工具[转载]
    IC设计的前端和后端(转)
    [转载]深入理解JavaScript系列 --汤姆大叔
    xml的特殊字符
    JavaScript 对象
    knockoutjs关于ko.bindingHandlers的updata订阅
    单元测试 unittest 读取文件 (CSV, XML)
    单元测试 unittest 将断言结果生成测试报告
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/POJ2676.html
Copyright © 2020-2023  润新知