Назад к лучшим решениям Status: AC, problem ZSUD, contest ZEL07. By ajaysomani (Ajay Somani), 2007-03-09 17:05:33.
  1. /* Author - Ajay Somani */
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cctype>
  7. #include<algorithm>
  8. #include<iterator>
  9. #include<map>
  10. #include<vector>
  11. #include<list>
  12. #include<set>
  13. #include<queue>
  14. #include<cassert>
  15. #include<deque>
  16. #include<stack>
  17. #include<bitset>
  18. #include<functional>
  19. #include<numeric>
  20. #include<utility>
  21. #include<sstream>
  22. #include<iomanip>
  23. #include<string>
  24. #include<cmath>
  25. #include<ctime>
  26. using namespace std;
  27.  
  28. #define Debug 0
  29. #define LET(x,a) __typeof(a) x(a)
  30. #define IFOR(i,a,b) for(LET(i,a);i!=(b);++i)
  31. #define EACH(it,v) IFOR(it,v.begin(),v.end())
  32. #define FOR(i,a,b) for(int i=(int)(a) ; i < (int)(b);i++)
  33. #define REP(i,n) FOR(i,0,n)
  34. #define SZ size()
  35. #define PB push_back
  36. #define PF push_front
  37.  
  38. #define V(x) vector< x >
  39. typedef V(int) VI;
  40. typedef V(VI) VII;
  41. typedef V(string) VS;
  42. typedef long long LL;
  43. typedef long double LD;
  44. typedef pair<int,int> PI;
  45.  
  46. #define INF 100000000
  47.  
  48. /***
  49. * number of nodes in the dancing link for 16x16 sudoku = 16*16*16*4 + 16*16*4 + 1 = 17409
  50. * The number of selected rows = 256
  51. * Number of column headers = 1024
  52. ***/
  53. #define nodes 3241
  54. #define maxSelected 81
  55. #define nHeaders 325
  56. char a[16][20];
  57.  
  58. class dancingLink{
  59. /* Algorithm assumes that the root node is 0 and all column headers are [1,1024] */
  60. public:
  61. /* Data objects */
  62. int l[nodes],r[nodes],u[nodes],d[nodes],C[nodes],size[nHeaders],o[maxSelected],initialChoice,h;
  63. /* this part is problem specific and to be implemented by the user */
  64. dancingLink(); /* initialization of the dancing links :D */
  65. void print(int k); /* output function .... specific to the problem */
  66. int row(int x); /* returns the row of a particular node */
  67. int choice(int col,int i); /* It gives the index of ith 1 in column col */
  68.  
  69. /* this part remains the same irrespective of the problem */
  70. void cover(int x){ /* A function to cover a particular column c */
  71. l[r[x]] = l[x];
  72. r[l[x]] = r[x];
  73. int i = x,j;
  74. while((i = d[i]) != x){
  75. j = i;
  76. while((j = r[j]) != i){
  77. size[C[j]]--;
  78. d[u[j]] = d[j];
  79. u[d[j]] = u[j];
  80. }
  81. }
  82. }
  83. void uncover(int x){/* A function to uncover a partucular column c */
  84. int i=x,j;
  85. while((i = u[i]) != x){
  86. j = i;
  87. while((j = l[j]) != i){
  88. size[C[j]]++;
  89. u[d[j]] = j;
  90. d[u[j]] = j;
  91. }
  92. }
  93. r[l[x]] = x;
  94. l[r[x]] = x;
  95. }
  96. bool search(int k){/* a function which finds the solution using backtracking with algorithm 'X' */
  97. if(r[h] == h){
  98. print(k);return true;
  99. }
  100. int c,s=INF,cur = h,j;
  101. while((cur = r[cur]) != h){
  102. if(size[cur] < s) s = size[c = cur];
  103. }
  104. cover(cur = c);
  105. while((cur = d[cur]) != c){
  106. o[k] = row(j = cur);
  107. while((j = r[j]) != cur){
  108. cover(C[j]);
  109. }
  110. if(search(k+1)){
  111. return true;
  112. }
  113. while((j = l[j]) != cur){
  114. uncover(C[j]);
  115. }
  116. }
  117. uncover(c);
  118. return false;
  119. }
  120. };
  121. dancingLink::dancingLink():h(0),initialChoice(0){
  122. REP(i,nHeaders){
  123. r[i] = (i+1)%nHeaders;
  124. l[i] = (i+nHeaders-1)%nHeaders;
  125. size[i] = 9;
  126. }
  127. FOR(i,nHeaders,nodes){
  128. r[i] = ((i-nHeaders)/4)*4 + ((i-nHeaders)%4+1)%4 + nHeaders;
  129. l[i] = ((i-nHeaders)/4)*4 + ((i-nHeaders)%4+3)%4 + nHeaders;
  130. }
  131. int temp[10];
  132. FOR(i,1,nHeaders){
  133. temp[0] = i;
  134. REP(j,9){ temp[j+1] = choice(i-1,j);C[temp[j+1]] = i;}
  135. REP(j,10){ d[temp[j]] = temp[(j+1)%10];u[temp[j]] = temp[(j+9)%10];}
  136. }
  137. /*REP(i,9) puts(a[i]);putchar(10);*/
  138. REP(i,9) REP(j,9) if(a[i][j] != '.'){
  139. int cur = (i*81+j*9+(a[i][j]-'1')),z;
  140. o[initialChoice++] = cur;
  141. z = (cur = cur * 4 + nHeaders);
  142. while((z = r[z]) != cur){
  143. cover(C[z]);
  144. }
  145. cover(C[z]);
  146. }
  147. }
  148. int dancingLink::choice(int col,int no){
  149. if(col < 81){
  150. return (col*9+no)*4 + nHeaders;
  151. }
  152. else if(col < 162){
  153. col -= 81;
  154. return ((col/9)*81+no*9+col%9)*4+1+nHeaders;
  155. }
  156. else if(col < 243){
  157. col -= 162;
  158. return (no*81+(col/9)*9+col%9)*4+2+nHeaders;
  159. }
  160. else {
  161. col -= 243;
  162. return ((((col/9)/3)*3+(no/3))*81 + (((col/9)%3)*3+no%3)*9 + col%9)*4+3+nHeaders;
  163. }
  164. }
  165. void dancingLink::print(int k){
  166. assert(k == 81);
  167. REP(i,k) a[o[i]/81][(o[i]/9)%9]='1'+o[i]%9;
  168. printf("Y\n");
  169. REP(i,9) printf(a[i]);
  170. putchar(10);
  171. }
  172. int dancingLink::row(int x){
  173. return (x-nHeaders)/4;
  174. }
  175. int main(){
  176. int N;scanf("%d",&N);while(N--){
  177. char temp[100];scanf("%s",temp);
  178. REP(i,81) a[i/9][i%9] = temp[i];
  179. dancingLink r;
  180. r.search(r.initialChoice);
  181. }
  182. return 0;
  183. }