zoukankan      html  css  js  c++  java
  • Poj3074-Sudoku(数独DLX)

    题意: 给出一个9*9的矩阵,有一些格子已经填了数,有一些是.代表未填。求任意一组解使得每行包含1~9,每列包含1~9,每个小矩形(3*3)包含1~9。

    解析: 精确覆盖DLX的经典题目,每一行代表要填数的情况,列共有81*4行,第一个81行代表第i行j列放了数,第二个81列代表第i行放的数k,第三个81列

    代表第j列放的数k,第四个81行代表第i个小矩形放的数k。对于字符为.的情况添加9行,对于字符为数字的情况添加一行。然后就是跑一遍DLX,保存一下答案

    输出即可。

    代码

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int INF=1e9+7;
    const int ms=81*10;
    const int maxn=ms*4;
    int ans[maxn];
    struct DLX
    {
        int n,id;
        int L[maxn],R[maxn],U[maxn],D[maxn];
        int C[maxn],S[maxn],loc[maxn][3];
        int H[ms];
        void init(int nn=0)
        {
            n=nn;
            for(int i=0;i<=n;i++) U[i]=D[i]=i,L[i]=i-1,R[i]=i+1;
            L[0]=n; R[n]=0;
            id=n;
            memset(S,0,sizeof(S));
            memset(H,-1,sizeof(H));
        }
        void Link(int x,int y,int px,int py,int k)
        {
            ++id;
            D[id]=y; U[id]=U[y];
            D[U[y]]=id; U[y]=id;
            loc[id][0]=px,loc[id][1]=py,loc[id][2]=k;
            C[id]=y; S[y]++;
            if(H[x]==-1) H[x]=L[id]=R[id]=id;
            else
            {
                int a=H[x];
                int b=R[a];
                L[id]=a; R[a]=id;
                R[id]=b; L[b]=id;
                H[x]=id;
            }
        }
        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[C[j]]--;
            }
        }
        void Resume(int c)
        {
            for(int i=U[c];i!=c;i=U[i])
                for(int j=R[i];j!=i;j=R[j])
            {
                S[C[j]]++;
                U[D[j]]=j;
                D[U[j]]=j;
            }
            L[R[c]]=c;
            R[L[c]]=c;
        }
        bool dfs(int step)
        {
            if(step==81) return true;
            if(R[0]==0) return false;
            int Min=INF,c=-1;
            for(int i=R[0];i;i=R[i])
                if(Min>S[i]){ Min=S[i]; c=i; }
            Remove(c);
            for(int i=D[c];i!=c;i=D[i])
            {
                ans[step]=i;
                for(int j=R[i];j!=i;j=R[j]) Remove(C[j]);
                if(dfs(step+1)) return true;
                for(int j=L[i];j!=i;j=L[j]) Resume(C[j]);
            }
            Resume(c);
            return false;
        }
    }dlx;
    int main()
    {
        char S[90];
        while(scanf("%s",S)!=EOF)
        {
            if(S[0]=='e') break;
            dlx.init(81*4);
            int k=0,r=0;
            for(int x=0;x<9;x++)
                for(int y=0;y<9;y++)
            {
                char ch=S[k++];
                int a,b,c,d;
                if(ch=='.')
                {
                    for(int i=1;i<=9;i++)
                    {
                        a=x*9+y+1;
                        b=x*9+i+81;
                        c=y*9+i+81+81;
                        int s=(x/3)*3+y/3;
                        d=s*9+i+81+81+81;
                        ++r;
                        dlx.Link(r,a,x,y,i);
                        dlx.Link(r,b,x,y,i);
                        dlx.Link(r,c,x,y,i);
                        dlx.Link(r,d,x,y,i);
                    }
                }
                else
                {
                    int i=ch-'0';
                    a=x*9+y+1;
                    b=x*9+i+81;
                    c=y*9+i+81+81;
                    int s=(x/3)*3+y/3;
                    d=s*9+i+81+81+81;
                    ++r;
                    dlx.Link(r,a,x,y,i);
                    dlx.Link(r,b,x,y,i);
                    dlx.Link(r,c,x,y,i);
                    dlx.Link(r,d,x,y,i);
                }
            }
            dlx.dfs(0);
            int res[10][10];
            for(int i=0;i<81;i++)
            {
                int a=ans[i];
                int x=dlx.loc[a][0],y=dlx.loc[a][1],k=dlx.loc[a][2];
                res[x][y]=k;
            }
            for(int i=0;i<9;i++)
                for(int j=0;j<9;j++) printf("%d",res[i][j]);
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    《将博客搬至CSDN》
    2015-05-01 至 2015-07-30错误总结
    2015-01-01至2015-04-30错误积累
    2015-07-30 至 2016-03-16错误Note
    2014-11-21错误总结
    Spring 和 SpringMVC 的区别
    spring 容器加载
    Spring注解
    自定义拦截器
    Js闭包
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/5750581.html
Copyright © 2011-2022 走看看