• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            雪竹的天空

            theorix

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              34 隨筆 :: 0 文章 :: 20 評論 :: 0 Trackbacks

             數獨問題可以轉換為729行324列的exact cover 問題。每一行代表每個方格的可選值,每一列代表每個格的限制,建立雙向十字鏈表,即可用dancing links算法優化求解。

              1Source Code
              2
              3Problem: 3074  User: theorix 
              4Memory: 308K  Time: 47MS 
              5Language: C++  Result: Accepted 
              6
              7Source Code 
              8#include<iostream>
              9using namespace std;
             10#define RR 729
             11#define CC 324
             12#define INF 1000000000
             13int mem[RR+9];
             14int ans[RR+9];
             15char ch[RR+9];
             16int cnt[CC+9];
             17struct node
             18{
             19    int r,c;
             20    node *up;
             21    node *down;
             22    node *left;
             23    node *right;
             24}
            head,all[RR*CC+99],row[RR],col[CC];int all_t;
             25inline void link(int r,int c)
             26{
             27    cnt[c]++;
             28    node *t=&all[all_t++];
             29    t->r=r;
             30    t->c=c;
             31    t->left=&row[r];
             32    t->right=row[r].right;
             33    t->left->right=t;
             34    t->right->left=t;
             35    t->up=&col[c];
             36    t->down=col[c].down;
             37    t->up->down=t;
             38    t->down->up=t;
             39}

             40inline void remove(int c)
             41{
             42    node *t,*tt;
             43    col[c].right->left=col[c].left;
             44    col[c].left->right=col[c].right;
             45    for(t=col[c].down;t!=&col[c];t=t->down)
             46    {
             47        for(tt=t->right;tt!=t;tt=tt->right)
             48        {
             49            cnt[tt->c]--;
             50            tt->up->down=tt->down;
             51            tt->down->up=tt->up;
             52        }

             53        t->left->right=t->right;
             54        t->right->left=t->left;
             55    }

             56}

             57inline void resume(int c)
             58{
             59    node *t,*tt;
             60    for(t=col[c].down;t!=&col[c];t=t->down)
             61    {        
             62        t->right->left=t;
             63        t->left->right=t;
             64        for(tt=t->left;tt!=t;tt=tt->left)
             65        {
             66            cnt[tt->c]++;
             67            tt->down->up=tt;
             68            tt->up->down=tt;
             69        }

             70    }
                
             71    col[c].left->right=&col[c];
             72    col[c].right->left=&col[c];
             73}

             74bool solve(int k)
             75{
             76    if(head.right==&head)
             77        return true;
             78    node*t,*tt;
             79    int min=INF,tc;
             80    for(t=head.right;t!=&head;t=t->right)
             81    {
             82        if(cnt[t->c]<min)
             83        {
             84            min=cnt[t->c];
             85            tc=t->c;
             86            if(min<=1)break;
             87        }

             88    }

             89    remove(tc);
             90    for(t=col[tc].down;t!=&col[tc];t=t->down)
             91    {
             92        mem[k]=t->r;
             93        t->left->right=t;
             94        for(tt=t->right;tt!=t;tt=tt->right)
             95        {
             96            remove(tt->c);
             97        }

             98        t->left->right=t->right;
             99        if(solve(k+1))
            100            return true;
            101        t->right->left=t;
            102        for(tt=t->left;tt!=t;tt=tt->left)
            103        {
            104            resume(tt->c);
            105        }

            106        t->right->left=t->left;
            107    }

            108    resume(tc);
            109    return false;
            110}

            111int main()
            112{
            113    double ss=0;
            114    while(gets(ch))
            115    {
            116        int i,j,k;
            117        if(ch[0]=='e')break;
            118        all_t=1;
            119        memset(cnt,0,sizeof(cnt));
            120        head.left=&head;
            121        head.right=&head;
            122        head.up=&head;
            123        head.down=&head;
            124        head.r=RR;
            125        head.c=CC;
            126        for(i=0;i<CC;i++)
            127        {
            128            col[i].c=i;
            129            col[i].r=RR;
            130            col[i].up=&col[i];
            131            col[i].down=&col[i];
            132            col[i].left=&head;
            133            col[i].right=head.right;
            134            col[i].left->right=&col[i];
            135            col[i].right->left=&col[i];
            136        }

            137        for(i=0;i<RR;i++)
            138        {
            139            row[i].r=i;
            140            row[i].c=CC;
            141            row[i].left=&row[i];
            142            row[i].right=&row[i];
            143            row[i].up=&head;
            144            row[i].down=head.down;
            145            row[i].up->down=&row[i];
            146            row[i].down->up=&row[i];
            147        }

            148        for(i=0;i<RR;i++)
            149        {
            150            int r=i/9/9%9;
            151            int c=i/9%9;
            152            int val=i%9+1;
            153            if(ch[r*9+c]=='.'||ch[r*9+c]==val+'0')
            154            {
            155                link(i,r*9+val-1);
            156                link(i,81+c*9+val-1);
            157                int tr=r/3;
            158                int tc=c/3;
            159                link(i,162+(tr*3+tc)*9+val-1);
            160                link(i,243+r*9+c);
            161            }

            162        }

            163        for(i=0;i<RR;i++)
            164        {
            165            row[i].left->right=row[i].right;
            166            row[i].right->left=row[i].left;
            167        }

            168        solve(1);
            169        for(i=1;i<=81;i++)
            170        {
            171            int t=mem[i]/9%81;
            172            int val=mem[i]%9+1;
            173            ans[t]=val;
            174        }

            175        for(i=0;i<81;i++)
            176            printf("%d",ans[i]);
            177        printf("\n");
            178    }

            179}

            180
            181

             

            posted on 2008-09-01 02:01 雪竹的天空( theorix ) 閱讀(5809) 評論(8)  編輯 收藏 引用 所屬分類: 解題報告

            評論

            # re: 數獨的 Dancing links 解法(源代碼) 2008-09-01 02:12 <font color="red">雪竹的天空( theorix )
            TLE了幾天終于把這道數獨題過了
            呵呵 寫的還不錯  回復  更多評論
              

            # re: 數獨的 Dancing links 解法(含源代碼) 2008-11-27 16:39 梅雪香
            您好,向您請教一下,這個程序的輸入數據格式是怎么樣的呢?
            另外,我基本了解了dancing links的求解算法,但不太清楚如何把數獨問題轉化為精確覆蓋問題,也就是怎么初始化成為729行324列的exact cover 問題。
            能不能把這個轉換過程的思想描述一下呢?
            如肯賜教請發郵件到: mxx@vip.qq.com
            先謝謝您了.  回復  更多評論
              

            # re: 數獨的 Dancing links 解法(含源代碼) 2009-02-08 23:18 stranger
            http://en.wikipedia.org/wiki/Exact_cover  回復  更多評論
              

            # re: 數獨的 Dancing links 解法(含源代碼) 2009-02-25 14:37 ttylikl
            我將上面的代碼移植到C#竟然出了問題,真暈啊。。。  回復  更多評論
              

            # re: 數獨的 Dancing links 解法(含源代碼) 2009-06-03 20:41 doxi
            想問問,但如何把數獨問題轉化為精確覆蓋問題 謝謝大牛指點  回復  更多評論
              

            # re: 數獨的 Dancing links 解法(含源代碼) 2009-06-03 20:42 doxi

            想問問,但如何把數獨問題轉化為精確覆蓋問題 謝謝大牛指點 doxi
            我的郵箱 ; fanxicai2000@163.com  回復  更多評論
              

            # re: 數獨的 Dancing links 解法(含源代碼) 2010-05-08 15:46 批你
            靠啊,你確定你是對的嗎  回復  更多評論
              

            # re: 數獨的 Dancing links 解法(含源代碼) 2010-09-26 15:02 LitIce
            我認真研究了下你的程序,用他做noip2009靶形數獨。
            發現
            102 for(tt=t->left;tt!=t;tt=tt->left)
            如果把left改成right。。(其他對應)改動。
            也就是恢復的順序和刪除的順序相同,會Tle。
            而你現在這樣原路退回去恢復會快很多,并且不會Tle.
            能否解釋下。
            郵箱:13559542150@139.com
            期待你的回復……
            90 for(t=col[tc].down;t!=&col[tc];t=t->down)
            91 {
            92 mem[k]=t->r;
            93 t->left->right=t;
            94 for(tt=t->right;tt!=t;tt=tt->right)
            95 {
            96 remove(tt->c);
            97 }
            98 t->left->right=t->right;
            99 if(solve(k+1))
            100 return true;
            101 t->right->left=t;
            102 for(tt=t->left;tt!=t;tt=tt->left)
            103 {
            104 resume(tt->c);
            105 }
            106 t->right->left=t->left;
            107 }
              回復  更多評論
              

            婷婷综合久久中文字幕| 久久久久久综合一区中文字幕 | 亚洲熟妇无码另类久久久| 久久久久亚洲av无码专区导航 | 亚洲国产高清精品线久久| 日韩精品久久无码人妻中文字幕| 综合久久精品色| 成人国内精品久久久久影院VR| 潮喷大喷水系列无码久久精品| 久久免费视频1| 国内精品久久久久久不卡影院| 久久精品国产99久久丝袜| 久久综合久久久| 老司机国内精品久久久久| 久久精品国产亚洲AV无码娇色| 久久精品水蜜桃av综合天堂| 热久久视久久精品18| 中文字幕无码久久精品青草| 久久精品人人做人人爽电影| 久久精品国产福利国产秒| 久久精品国产精品亚洲| 久久精品无码av| 久久国产欧美日韩精品免费| 国产精品久久婷婷六月丁香| 色欲久久久天天天综合网| 国产91久久精品一区二区| 久久精品亚洲福利| 亚洲国产视频久久| 久久99精品久久久久婷婷| 欧美亚洲国产精品久久蜜芽| 四虎影视久久久免费观看| 国产∨亚洲V天堂无码久久久| 91精品国产91久久| 久久久久一本毛久久久| 久久国产精品无码HDAV| 久久激情五月丁香伊人| 久久综合鬼色88久久精品综合自在自线噜噜 | 久久精品无码一区二区三区免费| 亚洲综合久久夜AV | 99久久婷婷国产综合亚洲| 久久青草国产精品一区|