HDU 1426 dancing links解决数独问题

 题目大意:

这是一个最简单的数独填充题目,题目保证只能产生一种数独,所以这里的初始9宫格较为稠密,可以直接dfs也没有问题

但最近练习dancing links,这类数据结构解决数独无疑效率会高很多

dancing links的数独限制条件是:

1.每行有9个元素,共9行 对应dlx81列

2.每列有9个元素,共9行 对应dlx81列

3.每个九宫格有9个元素,共9行 对应dlx81列

4.81个格子,每个格子最多有一个数

 

  1 #include <iostream>

  2 #include <cstring>

  3 #include <cstdio>

  4 #include <algorithm>

  5 #include <queue>

  6 #include <climits>

  7 #include <cmath>

  8 

  9 using namespace std;

 10 #define N 1000

 11 #define MAXNODE 1000000

 12 const int INF = INT_MAX;

 13 const double eps = 1e-8;

 14 

 15 int a[10][10];

 16 char str[5];

 17 

 18 int belong[9][9] =  {

 19                         {1,1,1,2,2,2,3,3,3},

 20                         {1,1,1,2,2,2,3,3,3},

 21                         {1,1,1,2,2,2,3,3,3},

 22                         {4,4,4,5,5,5,6,6,6},

 23                         {4,4,4,5,5,5,6,6,6},

 24                         {4,4,4,5,5,5,6,6,6},

 25                         {7,7,7,8,8,8,9,9,9},

 26                         {7,7,7,8,8,8,9,9,9},

 27                         {7,7,7,8,8,8,9,9,9},

 28                     };

 29 struct DLX{

 30     int n ,m , size;

 31     int col[MAXNODE] , row[MAXNODE];

 32     int U[MAXNODE] , D[MAXNODE] , L[MAXNODE] , R[MAXNODE];

 33     int cnt_col[N] , first[N];

 34     int ans[100];

 35 

 36     void init(int _n , int _m)

 37     {

 38         n = _n , m = _m;

 39         size= m ;

 40         for(int i=0 ; i<=m ; i++){

 41             L[i] = i-1 , R[i] = i+1;

 42             U[i] = D[i] = i;

 43         }

 44         L[0] = m , R[m] = 0;

 45         for(int i=1 ; i<=m ; i++) cnt_col[i] = 0;

 46         for(int i=1 ; i<=n ; i++) first[i] = -1;

 47     }

 48 

 49     void link(int r , int c)

 50     {

 51         ++size;

 52         U[D[c]] = size , D[size] = D[c];

 53         U[size] = c , D[c] = size;

 54 

 55         if(first[r]<0) L[size]=R[size]=first[r] = size;

 56         else{

 57             L[R[first[r]]] = size , R[size] = R[first[r]];

 58             L[size] = first[r] , R[first[r]] = size;

 59         }

 60         row[size] = r , col[size] = c , cnt_col[c]++;

 61     }

 62 

 63     void Remove(int c)

 64     {

 65         L[R[c]] = L[c] , R[L[c]] = R[c];

 66         for(int i=D[c] ; i!=c ; i=D[i]){

 67             for(int j=R[i] ; j!=i ; j=R[j]){

 68                 U[D[j]] = U[j] , D[U[j]] = D[j];

 69                 cnt_col[col[j]]--;

 70             }

 71         }

 72     }

 73 

 74     void Resume(int c)

 75     {

 76         for(int i=U[c] ; i!=c ; i=U[i]){

 77             for(int j=L[i] ; j!=i ; j=L[j]){

 78                 U[D[j]] = D[U[j]] = j;

 79                 cnt_col[col[j]]++;

 80             }

 81         }

 82         L[R[c]] = R[L[c]] = c;

 83     }

 84 

 85     bool Dance(int d)

 86     {

 87         if(!R[0]){

 88             for(int i=0 ; i<d ; i++){

 89                     int r = (ans[i]-1)/81;

 90                     int c = ((ans[i]-1)%81)/9;

 91                     a[r][c] = ((ans[i]-1)%9)+1;

 92             }

 93             return true;

 94         }

 95         int st=R[0];

 96         for(int i=R[0] ; i!=0 ; i=R[i])

 97             if(cnt_col[i]<cnt_col[st])

 98                 st = i;

 99         Remove(st);

100         for(int i=D[st] ; i!=st ; i=D[i]){

101             ans[d] = row[i];

102             for(int j=R[i] ; j!=i ; j=R[j]) Remove(col[j]);

103             if(Dance(d+1)) return true;

104             for(int j=L[i] ; j!=i ; j=L[j]) Resume(col[j]);

105         }

106         Resume(st);

107         return false;

108     }

109 

110 }dlx;

111 

112 void printM()

113 {

114     for(int i=0 ; i<9 ; i++)

115         for(int j=0 ; j<9 ; j++){

116            if(j<8) printf("%d " , a[i][j]);

117            else printf("%d\n" , a[i][j]);

118         }

119 }

120 

121 int main()

122 {

123   //  freopen("a.in" , "r" , stdin);

124     int index=0;

125     bool flag = false;

126     while(~scanf("%s" , str))

127     {

128         if(flag) puts("");

129         flag = true;

130         if(str[0] == '?') a[index/9][index%9] = 0;

131         else a[index/9][index%9] = str[0]-'0';

132         index++;

133         while(index<81){

134             scanf("%s" , str);

135             if(str[0] == '?') a[index/9][index%9] = 0;

136             else a[index/9][index%9] = str[0]-'0';

137             index++;

138         }

139        // printM();

140         dlx.init(729 , 324);

141         for(int i=0 ; i<9 ; i++)

142             for(int j=0 ; j<9 ; j++)

143             {

144                 if(a[i][j]){

145                     dlx.link((i*9+j)*9+a[i][j] , i*9+a[i][j]);

146                     dlx.link((i*9+j)*9+a[i][j] , 81+j*9+a[i][j]);

147                     dlx.link((i*9+j)*9+a[i][j] , 162+(belong[i][j]-1)*9+a[i][j]);

148                     dlx.link((i*9+j)*9+a[i][j] , 243+i*9+j+1);

149                 }

150                 else{

151                     for(int k=1 ; k<=9 ; k++){

152                         dlx.link((i*9+j)*9+k , i*9+k);

153                         dlx.link((i*9+j)*9+k , 81+j*9+k);

154                         dlx.link((i*9+j)*9+k , 162+(belong[i][j]-1)*9+k);

155                         dlx.link((i*9+j)*9+k , 243+i*9+j+1);

156                     }

157                 }

158             }

159         dlx.Dance(0);

160 

161         printM();

162         index=0;

163     }

164 

165     return 0;

166 }

 

你可能感兴趣的:(link)