C#dance link 算法代码实现

来源:互联网 发布:多益网络老板广州首富 编辑:程序博客网 时间:2024/06/02 02:35

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Text;

using System.Diagnostics;

using System.Collections;

//该内核中run()方法接受一个数独字符串(既字符为0到9,长度为81),方法输出一个数独字符串(求解完毕的数独。如果无解则全部为0)

namespace 数独

{

    class dlx

    {

        const int RR = 729;

        const int CC = 324;

        const int INF = 1000000000;

        int[]mem = new int[RR+ 9];

        int[]ans = new int[RR+ 9];

        char[]ch = new char[RR+ 9];

        int[]cnt = new int[CC+ 9];

        class node

        {

            publicint r, c;

            publicnode up;

            publicnode down;

            publicnode left;

            publicnode right;

        };

        nodehead;

        node[]all = new node[RR* CC + 99];

        node[] row = new node[RR];

        node[]col = new node[CC];

        intall_t;

        voidlink(int r,intc)

        {

            cnt[c]++;

            nodet = all[all_t];

            if(t == null)

            {

                t = newnode();

               all[all_t] = t;

            }

            all_t++;

            t.r = r;

            t.c = c;

            t.left = row[r];

            t.right = row[r].right;

            t.left.right = t;

            t.right.left = t;

            t.up = col[c];

            t.down = col[c].down;

            t.up.down = t;

            t.down.up = t;

        }

        voidremove(int c)

        {

            nodet, tt;

            col[c].right.left = col[c].left;

            col[c].left.right = col[c].right;

            for(t = col[c].down; !Object.ReferenceEquals(t,col[c]); t = t.down)

            {

                for(tt = t.right; !Object.ReferenceEquals(tt,t); tt = tt.right)

                {

                    cnt[tt.c]--;

                    tt.up.down = tt.down;

                    tt.down.up = tt.up;

                }

                t.left.right = t.right;

                t.right.left = t.left;

            }

        }

        voidresume(int c)

        {

            nodet, tt;

            for(t = col[c].down; !Object.ReferenceEquals(t,col[c]); t = t.down)

            {

                t.right.left = t;

                t.left.right = t;

                for(tt = t.left; !Object.ReferenceEquals(tt,t); tt = tt.left)

                {

                    cnt[tt.c]++;

                    tt.down.up = tt;

                    tt.up.down = tt;

                }

            }

            col[c].left.right = col[c];

            col[c].right.left = col[c];

        }

        intsolve(int k)

        {

            if (Object.ReferenceEquals(head.right, head))

                return1;

            nodet, tt;

            intmin = INF, tc = 0;

            for(t = head.right; !Object.ReferenceEquals(t,head); t = t.right)

            {

                if(cnt[t.c] < min)

                {

                    min = cnt[t.c];

                    tc = t.c;

                    if(min <= 1) break;

                }

            }

            remove(tc);

            intscnt = 0;

            for(t = col[tc].down; !Object.ReferenceEquals(t,col[tc]); t = t.down)

            {

                mem[k] = t.r;

                t.left.right = t;

                for(tt = t.right; !Object.ReferenceEquals(tt,t); tt = tt.right)

                {

                    remove(tt.c);

                }

                t.left.right = t.right;

                scnt += solve(k + 1);

                if(!chk_unique && scnt == 1)

                    returnscnt;

                if(scnt > 1)

                    returnscnt;

                //继续找下个可能

                t.right.left = t;

                for(tt = t.left; !Object.ReferenceEquals(tt,t); tt = tt.left)

                {

                    resume(tt.c);

                }

                t.right.left = t.left;

            }

            resume(tc);

            returnscnt;

        }

        privatebool chk_unique =false;

        public int scount = 0;

        public int solution_count(Stringstr)

        {

            chk_unique = true;

            run(str);

            returnscount;

        }

        public String do_solve(Stringstr)

        {

            chk_unique = false;

            Stringret = run(str);

            if(scount != 1)

                return"";

            returnret;

        }

        public String run(Stringstr)

        {

            mem = newint[RR + 9];

            ans = newint[RR + 9];

            ch = newchar[RR + 9];

            Strings = str.Replace("\r","");

            s = s.Replace("\n","");

            ch = s.ToCharArray();

            cnt = newint[CC + 9];

            head = newnode();

            all = newnode[RR * CC + 99];

            row = newnode[RR];

            col = newnode[CC];

            {

                inti;

                all_t = 1;

                cnt = newint[CC + 9];

                head.left = head;

                head.right = head;

                head.up = head;

                head.down = head;

                head.r = RR;

                head.c = CC;

                for(i = 0; i < CC; i++)

                {

                    col[i] = newnode();

                    col[i].c = i;

                    col[i].r = RR;

                    col[i].up = col[i];

                    col[i].down = col[i];

                    col[i].left = head;

                    col[i].right = head.right;

                    col[i].left.right = col[i];

                    col[i].right.left = col[i];

                }

                for(i = 0; i < RR; i++)

                {

                    row[i] = new node();

                    row[i].r = i;

                    row[i].c = CC;

                    row[i].left = row[i];

                    row[i].right = row[i];

                    row[i].up = head;

                    row[i].down = head.down;

                    row[i].up.down = row[i];

                    row[i].down.up = row[i];

                }

                for(i = 0; i < RR; i++)

                {

                    intr = i / 9 / 9 % 9;

                    intc = i / 9 % 9;

                    intval = i % 9 + 1;

                    if(ch[r * 9 + c] =='.' || ch[r * 9 + c] == '0' || ch[r * 9 + c] == val + '0')

                    {

                        link(i, r * 9 + val -1);

                        link(i, 81 + c * 9 +val - 1);

                        int tr = r / 3;

                        int tc = c / 3;

                        link(i, 162 + (tr * 3 +tc) * 9 + val - 1);

                        link(i, 243 + r * 9 +c);

                    }

                }

                for(i = 0; i < RR; i++)

                {

                    row[i].left.right =row[i].right;

                    row[i].right.left =row[i].left;

                }

                scount = solve(1);

                for(i = 1; i <= 81; i++)

                {

                    intt = mem[i] / 9 % 81;

                    intval = mem[i] % 9 + 1;

                    ans[t] = val;

                }

                StringBuildersb =new StringBuilder();

                for(i = 0; i < 81; i++)

                {

                    sb.Append(ans[i]);

                }

                returnsb.ToString();

            }

        }

 

    }

}