• 51 nod 1211 数独 DLX


    原题链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1211

    调了挺久的,自己的一份舞蹈链模板……

    算是在网上见到的模板中比较短的一份吧(2.2K)

    #include<cstdio>
    #include<algorithm>
    #include<ctime>
    #define MN 300000
    using namespace std;
    int read_p,read_ca;
    inline int read(){
        read_p=0;read_ca=getchar();
        while(read_ca<'0'||read_ca>'9') read_ca=getchar();
        while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
        return read_p;
    }
    int n,m,l[MN],r[MN],d[MN],u[MN],X[MN],Y[MN],Z[MN],mmh[MN],st[MN],_MMH,_mmh[MN],_h[MN],map[10][10],_a[MN],top=0,c,Num,_L[MN],s[MN],MMH=0,NN=0,a,num=324,h=0;
    bool Bo[MN];
    inline void rec(){int x=st[top--];d[u[x]]=x;u[d[x]]=x;l[r[x]]=x;r[l[x]]=x;s[_L[x]]++;}
    inline void del(int x){if (Bo[_L[x]]) return;s[_L[x]]--;st[++top]=x;d[u[x]]=d[x];u[d[x]]=u[x];l[r[x]]=l[x];r[l[x]]=r[x];}
    inline void tadd(int l,int x){u[d[u[l]]=x]=u[l];d[u[l]=x]=l;_L[x]=l;s[l]++;}
    inline void hadd(int x,int y,int z){
        h++;X[h]=x;Y[h]=y;Z[h]=z;
        tadd(x*9-9+y,++num);tadd(x*9-9+z+81,++num);tadd(y*9-9+z+162,++num);tadd(((x-1)/3*3+(y+2)/3)*9-9+z+243,++num);
        r[num-3]=num-2;r[num-2]=num-1;r[num-1]=num;r[num]=num-3;
        l[num-3]=num;l[num-2]=num-3;l[num-1]=num-2;l[num]=num-1;
        _h[num-3]=_h[num-2]=_h[num-1]=_h[num]=h;
    }
    void work(int p){
        NN++;
        register int i,j,k,o;
        if (MMH==2) return;
        if (!r[0]){
            _MMH=p-1;
            for (i=1;i<=_MMH;i++) _mmh[i]=mmh[i];
            MMH++;
            return;
        }
        int bo=top,t,mr=1e9;c=0;
        for (i=r[0];i;i=r[i]){
            if (d[i]==i) return;
            if (mr>s[i]){
                mr=s[i];
                t=i;
            }
        }
        for (i=d[t];i!=t;i=d[i]){
            mmh[p]=_h[i];
            for (j=i;;j=r[j]){
                for (k=j;;k=d[k]){
                    for (o=k;;o=r[o]){
                        if (Bo[o]) break;
                        Bo[_a[++c]=o]=1;
                        if (r[o]==k||o<=324) break;
                    }
                    if (d[k]==j) break;
                }
                if (r[j]==i) break;
            }
            for (j=c;j;j--) del(_a[j]);
            while (c) Bo[_a[c--]]=0;
            work(p+1);
            while (top>bo) rec();
        }
    }
    int main(){
        register int i,j,k;
        for (i=0;i<=num;i++) l[i]=i==0?num:i-1,r[i]=i==num?0:i+1,u[i]=d[i]=i;
        for (i=1;i<=9;i++)
        for (j=1;j<=9;j++){
            a=read();
            if (a) hadd(i,j,a);else
            for (k=1;k<=9;k++) hadd(i,j,k);
        }
        work(1);
        if (MMH!=1) return printf("No Solution
    "),0;
        for (i=1;i<=_MMH;i++) map[X[_mmh[i]]][Y[_mmh[i]]]=Z[_mmh[i]];
        for (i=1;i<=9;printf("
    "),i++)
        for (j=1;j<=9;j++) printf("%d ",map[i][j]);
    }
    View Code
  • 相关阅读:
    Redis面试题 总结
    C++ 自由存储区是否等价于堆?(转)
    线程同步方式
    epoll的原理 (一)(转)
    C/C++ 中 volatile 关键字详解(转)
    Linux堆内存管理
    找出数组中出现次数超过一半的数
    剑指offer-复杂链表的复制
    已知二叉树前序中序遍历重建二叉树
    Linux常用命令
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5754499.html
Copyright © 2020-2023  润新知