zoukankan      html  css  js  c++  java
  • Dancing Links & Algorithm X

    1 参考链接

       http://www.cnblogs.com/steady/archive/2011/03/15/1984791.html#undefined

       http://en.wikipedia.org/wiki/Dancing_Links 

    2 双向链表

      可用数组实现

      删除x操作

      Function Remove

        x.left.right <-x.right

        x.right.left <- x.left

      恢复x

      Function Resume

        x.left.right <- x

        x.right.left <- x

    3 精确覆盖(Exact Cover Problem)

      给定一个01矩阵现在要选择一些行,使得每一列有且仅有一个1

      解决办法:搜索

    4 数独转化

      数独满足的条件:

        1. 每个格子都填有数字

        2. 每一行都要有1~9这9个数字填入

        3. 每一列都要有1~9这9个数字填入

        4. 每一坨都要有1~9这9个数字填入   

      可构造一个729*324的由01构成的矩阵

         //i,j,k表示在棋盘上i行j列填入数字k

        行:

          1到81,表示棋盘中9*9=81个格子是否填入了数字。如果是,则选取的01行在该01列上有1

            对应的01列编号为:(i-1)*9+j

          

          81+1到81*2,表示棋盘中9行,每行的9个不同的数字是否填入。棋盘上某行已经填入了某个数字,则在选取的01行上,对应的01列有1。

            对应的01列编号为:81+(i-1)*9+k。

          

          81*2+1到81*3,表示棋盘中9列,每列的9个不同的数字是否填入。

            对应的01列编号为:81*2+(j-1)*9+k。

          

          81*3+1到81*4,表示棋盘中9块,每块的9个不同的数字是否填入。

      

          01行是状态。数独做完后的状态是什么,就是棋盘上每个格子填入的究竟是什么数字

          所以,01行表示的是,棋盘上某个格子填入的是什么数字。

          那01行的行数就是9*9*9。

    5 Sample

    vijos 1345 数独大赛

      1 #include <cstdio>
      2 #include <cstring>
      3 
      4 const int MAXA = 10;
      5 const int MAXC = 324+10;
      6 const int MAXR = 729+10;
      7 const int MAXN = MAXR*4+MAXC;
      8 
      9 int n = 324, T;
     10 
     11 struct DancingLinks{
     12     char c;
     13     int sz, S[MAXC], 
     14         Col[MAXN], Row[MAXN], 
     15         L[MAXN], R[MAXN], U[MAXN], D[MAXN], 
     16         head[MAXA][MAXA][MAXA],
     17         anna[MAXA][MAXA];
     18 
     19     inline  void Clear(){
     20         memset(S, 0, sizeof(S));
     21         memset(Col, 0, sizeof(Col));
     22         for (int i=0; i<=81*4; i++)
     23             L[i] = i-1, R[i] = i+1,
     24             U[i] = i, D[i] = i;
     25         L[0] = n, R[n] = 0;
     26         sz = n;
     27     }
     28 
     29     inline void Scan(){
     30         do
     31             c = getchar();
     32         while (!(48<=c && c<=57));
     33 
     34         for (int i=1; i<=9; i++)
     35             for (int j=1; j<=9; j++)
     36                 anna[i][j] = c-48,
     37                 c = getchar();
     38     }
     39 
     40     inline void Print(){
     41         for (int i=1; i<=9; i++)
     42             for (int j=1; j<=9; j++)
     43                 printf("%d", anna[i][j]);
     44         printf("
    ");
     45     }
     46     
     47     inline int _GetPortion(int i,int j){
     48         return (--i/3)*3+(--j/3+1);
     49     }
     50 
     51     inline void AddNode(int c,int sz){
     52         U[D[c]] = sz, D[sz] = D[c];
     53         U[sz] = c, D[c] = sz;
     54         S[c] ++, Col[sz] = c;
     55     }
     56 
     57     inline void Remove(int c){
     58         L[R[c]] = L[c], R[L[c]] = R[c];
     59         for (int i=D[c]; i!=c; i=D[i])
     60             for (int j=R[i]; j!=i; j=R[j])
     61                 U[D[j]]=U[j], D[U[j]]=D[j],
     62                 -- S[Col[j]];
     63     }
     64 
     65     inline void Resume(int c){
     66         for (int i=U[c]; i!=c; i=U[i])
     67             for (int j=L[i]; j!=i; j=L[j])
     68                 U[D[j]] = j, D[U[j]] = j,
     69                 ++ S[Col[j]];
     70         L[R[c]] = c, R[L[c]] = c;
     71     }
     72 
     73     inline bool DFS(int k){
     74             if (k>81) return true;
     75     
     76             int c = R[0], temp;
     77             for (int i=R[0]; i!=0; i=R[i]){
     78                 if (!S[i]) return false;
     79                 if (S[i]<S[c]) c = i;
     80             }
     81             Remove(c);
     82 
     83             for (int i=D[c]; i!=c; i=D[i]){
     84                 temp = Row[i];
     85                 anna[temp/100][(temp/10)%10] = temp%10;
     86                 for (int j=R[i]; j!=i; j=R[j])
     87                     Remove(Col[j]);
     88         
     89                 if (DFS(k+1)) return true;
     90         
     91                 for (int j=L[i]; j!=i; j=L[j])
     92                     Resume(Col[j]);
     93             }
     94             Resume(c);
     95     
     96             return false;
     97         }
     98 
     99         inline void AddRow(int i, int j, int k){
    100             for (int u=1; u<=4; u++)
    101                 L[sz+u] = sz+u-1, R[sz+u] = sz+u+1,
    102                 Row[sz+u] = 100*i+10*j+k;
    103                 
    104             L[sz+1] = sz+4, R[sz+4] = sz+1;
    105             head[i][j][k] = sz+1;
    106             AddNode(81*0+(i-1)*9+j, ++sz);
    107             AddNode(81*1+(i-1)*9+k, ++sz);
    108             AddNode(81*2+(j-1)*9+k, ++sz);
    109             AddNode(81*3+(_GetPortion(i,j)-1)*9+k, ++sz);
    110         }
    111         
    112         inline void EatCarrot(){
    113             Clear();
    114             Scan();
    115             
    116             for (int i=1; i<=9; i++)
    117                 for (int j=1; j<=9; j++)    
    118                     if (anna[i][j]) AddRow(i, j, anna[i][j]);
    119                     else
    120                         for (int k=1;k<=9;k++)
    121                             AddRow(i, j, k);
    122             
    123             int k = 0;
    124             for (int i=1; i<=9; i++)
    125                 for (int j=1; j<=9; j++)
    126                     if (anna[i][j]){
    127                         ++ k;
    128                         Remove(Col[head[i][j][anna[i][j]]]);
    129                         for (int u=R[head[i][j][anna[i][j]]]; u!=head[i][j][anna[i][j]]; u=R[u])
    130                             Remove(Col[u]);
    131                     }
    132 
    133             DFS(k+1);
    134             Print();
    135         }
    136 }Rabbit;
    137 
    138 int main(){
    139     scanf("%d", &T);
    140     while (T--) 
    141         Rabbit.EatCarrot();
    142 }
    vijos 1345

    wikioi 2924数独挑战

      1 #include <cstdio>
      2 #include <cstring>
      3 
      4 const int MAXA = 10;
      5 const int MAXC = 324+10;
      6 const int MAXR = 729+10;
      7 const int MAXN = MAXR*4+MAXC;
      8 
      9 int n = 324, T;
     10 
     11 struct DancingLinks{
     12     int sz, S[MAXC], 
     13         Col[MAXN], Row[MAXN], 
     14         L[MAXN], R[MAXN], U[MAXN], D[MAXN], 
     15         head[MAXA][MAXA][MAXA],
     16         anna[MAXA][MAXA];
     17 
     18     inline  void Clear(){
     19         memset(S, 0, sizeof(S));
     20         memset(Col, 0, sizeof(Col));
     21         for (int i=0; i<=81*4; i++)
     22             L[i] = i-1, R[i] = i+1,
     23             U[i] = i, D[i] = i;
     24         L[0] = n, R[n] = 0;
     25         sz = n;
     26     }
     27 
     28     inline void Scan(){
     29         for (int i=1; i<=9; i++)
     30             for (int j=1; j<=9; j++)
     31                 scanf("%d", &anna[i][j]);
     32     }
     33 
     34     inline void Print(){
     35         for (int i=1; i<=9; i++){
     36             for (int j=1; j<=9; j++)
     37                 printf("%d ", anna[i][j]);
     38             printf("
    ");
     39         }
     40     }
     41     
     42     inline int _GetPortion(int i,int j){
     43         return (--i/3)*3+(--j/3+1);
     44     }
     45 
     46     inline void AddNode(int c,int sz){
     47         U[D[c]] = sz, D[sz] = D[c];
     48         U[sz] = c, D[c] = sz;
     49         S[c] ++, Col[sz] = c;
     50     }
     51 
     52     inline void Remove(int c){
     53         L[R[c]] = L[c], R[L[c]] = R[c];
     54         for (int i=D[c]; i!=c; i=D[i])
     55             for (int j=R[i]; j!=i; j=R[j])
     56                 U[D[j]]=U[j], D[U[j]]=D[j],
     57                 -- S[Col[j]];
     58     }
     59 
     60     inline void Resume(int c){
     61         for (int i=U[c]; i!=c; i=U[i])
     62             for (int j=L[i]; j!=i; j=L[j])
     63                 U[D[j]] = j, D[U[j]] = j,
     64                 ++ S[Col[j]];
     65         L[R[c]] = c, R[L[c]] = c;
     66     }
     67 
     68     inline bool DFS(int k){
     69             if (k>81) return true;
     70     
     71             int c = R[0], temp;
     72             for (int i=R[0]; i!=0; i=R[i]){
     73                 if (!S[i]) return false;
     74                 if (S[i]<S[c]) c = i;
     75             }
     76             Remove(c);
     77 
     78             for (int i=D[c]; i!=c; i=D[i]){
     79                 temp = Row[i];
     80                 anna[temp/100][(temp/10)%10] = temp%10;
     81                 for (int j=R[i]; j!=i; j=R[j])
     82                     Remove(Col[j]);
     83         
     84                 if (DFS(k+1)) return true;
     85         
     86                 for (int j=L[i]; j!=i; j=L[j])
     87                     Resume(Col[j]);
     88             }
     89             Resume(c);
     90     
     91             return false;
     92         }
     93 
     94         inline void AddRow(int i, int j, int k){
     95             for (int u=1; u<=4; u++)
     96                 L[sz+u] = sz+u-1, R[sz+u] = sz+u+1,
     97                 Row[sz+u] = 100*i+10*j+k;
     98                 
     99             L[sz+1] = sz+4, R[sz+4] = sz+1;
    100             head[i][j][k] = sz+1;
    101             AddNode(81*0+(i-1)*9+j, ++sz);
    102             AddNode(81*1+(i-1)*9+k, ++sz);
    103             AddNode(81*2+(j-1)*9+k, ++sz);
    104             AddNode(81*3+(_GetPortion(i,j)-1)*9+k, ++sz);
    105         }
    106         
    107         inline void EatCarrot(){
    108             Clear();
    109             Scan();
    110             
    111             for (int i=1; i<=9; i++)
    112                 for (int j=1; j<=9; j++)    
    113                     if (anna[i][j]) AddRow(i, j, anna[i][j]);
    114                     else
    115                         for (int k=1;k<=9;k++)
    116                             AddRow(i, j, k);
    117             
    118             int k = 0;
    119             for (int i=1; i<=9; i++)
    120                 for (int j=1; j<=9; j++)
    121                     if (anna[i][j]){
    122                         ++ k;
    123                         Remove(Col[head[i][j][anna[i][j]]]);
    124                         for (int u=R[head[i][j][anna[i][j]]]; u!=head[i][j][anna[i][j]]; u=R[u])
    125                             Remove(Col[u]);
    126                     }
    127 
    128             DFS(k+1);
    129             Print();
    130         }
    131 }Rabbit;
    132 
    133 int main(){
    134     Rabbit.EatCarrot();
    135 }
    wikioi 2924
  • 相关阅读:
    python绘制图的度分布柱状图, draw graph degree histogram with Python
    一波儿networkx 读写edgelist,给节点加attribute的操作
    Graph Convolutional Network
    C++ | 使用成员初始化列表对成员数据初始化
    C++ | 运算符new和delete
    C++ | 强制类型转换
    C++ | 作用域运算符“::”
    C++ | 内联函数 inline
    VS DEBUG
    消息中间件 | 消息协议 | AMQP -- 《分布式 消息中间件实践》笔记
  • 原文地址:https://www.cnblogs.com/cjhahaha/p/3875059.html
Copyright © 2011-2022 走看看