• <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无码久久| 国产福利电影一区二区三区久久久久成人精品综合 | 97久久久久人妻精品专区| 污污内射久久一区二区欧美日韩 | 亚洲精品无码专区久久久| 2021久久精品免费观看| 亚洲欧美国产日韩综合久久| 日本久久中文字幕| 亚洲国产小视频精品久久久三级 | 久久综合久久综合亚洲| 久久99热这里只频精品6| 噜噜噜色噜噜噜久久| 97香蕉久久夜色精品国产| 伊人久久大香线蕉综合Av | 久久久久国产精品嫩草影院| 国产精品久久新婚兰兰| 色综合久久久久综合体桃花网| 久久99热只有频精品8| 青青草国产精品久久久久| 99久久国产主播综合精品| 日韩精品无码久久一区二区三| 久久亚洲AV无码精品色午夜| 亚洲色欲久久久综合网东京热| 国产精品对白刺激久久久| 99精品伊人久久久大香线蕉| 久久涩综合| 久久狠狠高潮亚洲精品| 久久精品亚洲男人的天堂| 99精品久久久久久久婷婷| 久久99国产综合精品免费| 九九热久久免费视频| 99蜜桃臀久久久欧美精品网站| 久久精品男人影院| 久久精品一区二区三区AV| 日本精品久久久久中文字幕8 | 精品国产乱码久久久久久人妻 | 久久www免费人成看片| 99久久精品国产毛片| 国产精品久久新婚兰兰 | 久久996热精品xxxx| 久久亚洲精品成人AV|