zoukankan      html  css  js  c++  java
  • dancing link X

    今天上午看了看dlx算法,感觉非常巧妙。这里就用数独来举例子好了。

    dancing link算法可以用来解决精确覆盖和重复覆盖问题。我暂时只会精确覆盖问题。我们用一个01矩阵来记录我们需要的东西。怎么说呢,就用数独来说吧。我们需要每一行每一列每一宫都只有一个1~9,所以说对于9*9=81个位置,我们得到了4个条件:

    1,当前位置只能放一个数。

    2,当前位置那一行只能放一种这个数。

    3,当前位置那一列只能放一种这个数。

    4,当前位置那一宫只能放这一个数。

    所以我们关于这三个条件都有9*9种状态,然后81个位置每个位置可以放1~9,所以我们就得到了一个729*324的01矩阵。剩下的就是套板就行了。

    dancing之所以快,是因为它的矩阵大小随着递归层数的增加,越来越小。并且它只记录了1的位置,大大缩短了时间。

    接下来是数独的板,数独游戏弱爆了。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 using namespace std;
      5 #define rp(x,y) (x)*9+y+81
      6 #define cp(x,y) (x)*9+y+162
      7 #define pp(x,y) (x)*9+y+243
      8 const int N = 60003;
      9 const int INF = 0x7fffffff;
     10 int u[N],d[N],L[N],R[N];
     11 int X[N],C[N],s[1003],h[1003],tot,id,ans[103];
     12 bool mark[1003];
     13 struct data {
     14     int pos,val;
     15 }a[1003],q[103];
     16 inline void del(int c) {
     17     L[R[c]] = L[c] ; R[L[c]] = R[c];
     18     for(int i = d[c] ; i != c ; i = d[i])
     19         for(int j = R[i] ; j != i ; j = R[j])
     20             d[u[j]] = d[j] , u[d[j]] = u[j] , s[C[j]]--;
     21 }
     22 inline void add(int c) {    
     23     L[R[c]] = R[L[c]] = c;
     24     for(int i = u[c] ; i != c ; i = u[i])
     25         for(int j = L[i] ; j != i ; j = L[j])
     26             d[u[j]] = u[d[j]] = j , s[C[j]]++;
     27 }
     28 inline void link(int r,int c) {
     29     s[c]++ ; C[++tot] = c ; X[tot] = r;
     30     u[tot] = c ; d[tot] = d[c];
     31     u[d[tot]] = tot ; d[u[tot]] = tot;
     32     if(h[r]==-1) {
     33         h[r] = L[tot] = R[tot] = tot;
     34     } else {
     35         L[tot] = h[r] ; R[tot] = R[h[r]];
     36         L[R[tot]] = tot ; R[L[tot]] = tot;
     37     }
     38 }
     39 inline bool dance(int k) {
     40     if(R[0]==0) {
     41         for(int i = 1 ; i <= 81 ; ++i) ans[q[i].pos] = q[i].val;
     42         for(int i = 1 ; i <= 81 ; ++i) printf("%d",ans[i]);
     43         printf("
    ");
     44         return 1;
     45     }
     46     int temp = INF , c = R[0];
     47     for(int i = R[0] ; i ; i = R[i])
     48         if(s[i] < temp) temp = s[i] , c = i;
     49     del(c);
     50     for(int i = d[c] ; i != c ; i = d[i]) {
     51         q[k+1] = a[X[i]];
     52         for(int j = R[i] ; j != i ; j = R[j]) del(C[j]);
     53         if(dance(k+1)) return 1;
     54         for(int j = L[i] ; j != i ; j = L[j]) add(C[j]);
     55     }
     56     add(c);
     57     return 0;
     58 }
     59 char ch[203];
     60 int main() {
     61     while(scanf("%s",ch+1)) {
     62         if(ch[1]=='e') return 0;
     63         id = tot = 0;
     64         memset(h,-1,sizeof(h));
     65         memset(mark,0,sizeof(mark));
     66         for(int i = 0 ; i <= 4*81 ; ++i) {
     67             R[i] = i + 1 ; L[i+1] = i;
     68             u[i] = d[i] = i;
     69             s[i] = 0;
     70         }
     71         L[0] = 4*81 ; R[4*81] = 0 ; tot = 4*81;
     72         for(int i = 0 ; i < 9 ; ++i) 
     73             for(int j = 0 ; j < 9 ; ++j)
     74                 if(ch[i*9+j+1]!='.') {
     75                     int t = ch[i*9+j+1]-'0' , p = i/3*3+j/3;
     76                     mark[rp(i,t)] = mark[cp(j,t)] = mark[pp(p,t)] = 1;
     77                 }
     78         for(int i = 0 ; i < 9 ; ++i)
     79             for(int j = 0 ; j < 9 ; ++j) {
     80                 int t = ch[i*9+j+1]!='.'?ch[i*9+j+1]-'0':0;
     81                 int p = i/3*3+j/3;
     82                 if(t) {
     83                     id++ ; a[id].pos = i*9+j+1 ; a[id].val = t;
     84                     link(id,i*9+j+1);
     85                     link(id,rp(i,t));
     86                     link(id,cp(j,t));
     87                     link(id,pp(p,t));
     88                 } else {
     89                     for(int k = 1 ; k <= 9 ; ++k) {
     90                         if(!mark[rp(i,k)]&&!mark[cp(j,k)]&&!mark[pp(p,k)]) {
     91                             id++ ; a[id].pos = i*9+j+1 ; a[id].val = k;
     92                             link(id,i*9+j+1);
     93                             link(id,rp(i,k));
     94                             link(id,cp(j,k));
     95                             link(id,pp(p,k));
     96                         }
     97                     }
     98                 }
     99             }
    100         dance(0);
    101     }
    102 }
    View Code
  • 相关阅读:
    电脑开机时一直滴滴的响开不了机是为什么?
    电脑开机时一直滴滴的响开不了机是为什么?
    winform窗体应用实现淡入淡出等效果
    winform窗体应用实现淡入淡出等效果
    windows-如何生成转储(dmp)文件--工具篇
    面向对象(三)- Java类的方法
    面向对象 (二)- Java类的属性
    面向对象 (二)- Java类的属性
    面向对象 (一)- Java中的类和对象
    面向对象 (一)- Java中的类和对象
  • 原文地址:https://www.cnblogs.com/registerzxr/p/5142218.html
Copyright © 2011-2022 走看看