传送门:http://poj.org/problem?id=3074

DLX 数独的9*9的模板题。

具体建模详见下面这篇论文。其中9*9的数独怎么转化到精确覆盖问题,以及相关矩阵行列的定义都在下文中,描述的十分清晰

http://wenku.baidu.com/view/4ab7bd00a6c30c2259019eae.html

有关Dancing Links的英文论文详见下面链接

http://wenku.baidu.com/view/60eb28ded15abe23482f4d77.html

中文的:

http://wenku.baidu.com/view/d8f13dc45fbfc77da269b126.html

AC代码:

  1. #include<iostream>
  2. #include<cstring>
  3. #include<string>
  4. #include<cstdio>
  5. #include<algorithm>
  6. #include<vector>
  7. #include<algorithm>
  8.  
  9. using namespace std;
  10. // 列:(行+列+块)*9种可能+9*9个格子
  11. // 行: 9*9*9 表示第i行第j列填k
  12. const int MAXN=(9+9+9)*9+9*9+9*9*9*9*9*4+10;
  13. #define INF 0xFFFFFF
  14. int size;
  15. int head,sz;
  16. int U[MAXN],D[MAXN],L[MAXN],R[MAXN];
  17. int H[MAXN],ROW[MAXN],C[MAXN],S[MAXN],O[MAXN];
  18.  
  19. void remove(int c)
  20. {
  21. L[R[c]]=L[c];
  22. R[L[c]]=R[c];
  23. for(int i=D[c];i!=c;i=D[i])
  24. {
  25. for(int j=R[i];j!=i;j=R[j])
  26. {
  27. U[D[j]]=U[j];
  28. D[U[j]]=D[j];
  29. --S[C[j]];
  30. }
  31. }
  32. }
  33.  
  34. void resume(int c)
  35. {
  36. for(int i=U[c];i!=c;i=U[i])
  37. {
  38. for(int j=L[i];j!=i;j=L[j])
  39. {
  40. ++S[C[j]];
  41. U[D[j]]=j;
  42. D[U[j]]=j;
  43. }
  44. }
  45. L[R[c]]=c;
  46. R[L[c]]=c;
  47. }
  48.  
  49. bool dfs(int k)
  50. {
  51. if(R[head]==head)
  52. {
  53. sort(O,O+9*9);
  54. int p=0;
  55. for(int i=0;i<9;i++)
  56. {
  57. for(int j=0;j<9;j++)
  58. {
  59. int num=O[p++];
  60. //cout<<num<<endl;
  61. num=num-(i*9+j)*9;
  62. printf("%d",num);
  63. }
  64. }
  65. printf("\n");
  66. return true;
  67. }
  68. int s=INF,c;
  69. for (int t=R[head];t!=head;t=R[t])
  70. {
  71. if (S[t]<s)
  72. {
  73. s=S[t];
  74. c=t;
  75. }
  76. }
  77. remove(c);
  78. for(int i=D[c];i!=c;i=D[i])
  79. {
  80. O[k]=ROW[i];
  81. for(int j=R[i];j!=i;j=R[j])
  82. remove(C[j]);
  83. if(dfs(k+1))
  84. return true;
  85. for(int j=L[i];j!=i;j=L[j])
  86. resume(C[j]);
  87. }
  88. resume(c);
  89. return false;
  90. }
  91.  
  92. void initDL(int n)
  93. {
  94. head=0;
  95. for(int i=0;i<=n;i++)
  96. {
  97. U[i]=i;D[i]=i;
  98. L[i]=i-1;R[i]=i+1;
  99. S[i]=0;
  100. }
  101. R[n]=0;L[0]=n;S[0]=INF+1;
  102. sz=n+1;
  103. memset(H,0,sizeof(H));
  104. }
  105.  
  106. void insert(int i, int j)
  107. {
  108. if(H[i])
  109. {
  110. L[sz]=L[H[i]];
  111. R[sz]=H[i];
  112. L[R[sz]]=sz;
  113. R[L[sz]]=sz;
  114. }
  115. else
  116. {
  117. L[sz]=sz;
  118. R[sz]=sz;
  119. H[i]=sz;
  120. }
  121. U[sz]=U[j];
  122. D[sz]=j;
  123. U[D[sz]]=sz;
  124. D[U[sz]]=sz;
  125. C[sz]=j;
  126. ROW[sz]=i;
  127. ++S[j];
  128. ++sz;
  129. }
  130.  
  131. char str[200];
  132.  
  133. void build()
  134. {
  135. int p=0;
  136. initDL(9*9*4);
  137. for(int i=0;i<9;i++)
  138. for(int j=1;j<=9;j++,p++)
  139. {
  140. int base=(i*9+j-1)*9;
  141. if(str[p]=='.')
  142. {
  143. for(int k=1;k<=9;k++)
  144. {
  145. int r;
  146. r=base+k;
  147. //第i行有数字k
  148. insert(r,i*9+k);
  149. //第j列有数字k
  150. insert(r,9*9+(j-1)*9+k);
  151. //第k块有数字k
  152. int block=(j-1)/3*3+i/3;
  153. insert(r,9*9*2+block*9+k);
  154. //第i行j列有一个数字(限制一个格子只填一个数)
  155. insert(r,9*9*3+i*9+j);
  156. }
  157. }
  158. else
  159. {
  160. int k=str[p]-'0';
  161. int r=base+k;
  162. //第i行有数字k
  163. insert(r,i*9+k);
  164. //第j列有数字k
  165. insert(r,9*9+(j-1)*9+k);
  166. //第k块有数字k
  167. int block=(j-1)/3*3+i/3;
  168. insert(r,9*9*2+block*9+k);
  169. //第i行j列有一个数字(限制一个格子只填一个数)
  170. insert(r,9*9*3+i*9+j);
  171. }
  172. }
  173. }
  174.  
  175. int main()
  176. {
  177. size=9; //9*9数独
  178. while(~scanf("%s",str))
  179. {
  180. if(strcmp(str,"end")==0)
  181. break;
  182. build();
  183. dfs(0);
  184. }
  185. return 0;
  186. }

POJ 3074 Sudoku (Dancing Links)的更多相关文章

  1. 算法实践——舞蹈链(Dancing Links)算法求解数独

    在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dancing Links)算法求解精确覆盖问题. 本文介绍该算法的实际运用,利用舞蹈链(Dancin ...

  2. 转载 - 算法实践——舞蹈链(Dancing Links)算法求解数独

    出处:http://www.cnblogs.com/grenet/p/3163550.html 在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dan ...

  3. 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...

  4. [转] 舞蹈链(Dancing Links)——求解精确覆盖问题

    转载自:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个 ...

  5. 算法帖——用舞蹈链算法(Dancing Links)求解俄罗斯方块覆盖问题

    问题的提出:如下图,用13块俄罗斯方块覆盖8*8的正方形.如何用计算机求解? 解决这类问题的方法不一而足,然而核心思想都是穷举法,不同的方法仅仅是对穷举法进行了优化 用13块不同形状的俄罗斯方块(每个 ...

  6. 【POJ3740】Easy Finding DLX(Dancing Links)精确覆盖问题

    题意:多组数据,每组数据给你几行数,要求选出当中几行.使得每一列都有且仅有一个1.询问是可不可行,或者说能不能找出来. 题解:1.暴搜.2.DLX(Dancing links). 本文写的是DLX. ...

  7. 转载 - 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    出处:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 ...

  8. 【POJ3074】Sudoku DLX(Dancing Links)

    数独就要DLX,不然不乐意. 数独的DLX构造:9*9个点每一个点有9种选择,这构成了DLX的729行,每行.列.阵有限制,均为9行(/列/阵),然后每行(/列/阵)都有九种数的情况.于是就有了3*9 ...

  9. ZOJ 3209 Treasure Map (Dancing Links)

    Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 KB Your boss once had got many copies of ...

随机推荐

  1. oracle 11g在安装过程中出现监听程序未启动或数据库服务未注册到该监听程序

    15511477451 原文 oracle 11g在安装过程中出现监听程序未启动或数据库服务未注册到该监听程序? 环境:win7 64位系统.oracle11g数据库 问题描述:在win7 64位系统 ...

  2. 手势解锁自定义View

    package com.rxx.view; import java.util.ArrayList; import java.util.List; import java.util.Timer; imp ...

  3. Dapper.net 在Parameterized时对于String的扩展(转)

    虽然Dapper通过提供的DbString本身支持对于String的指定Parameterized,但这方法明显不够,当Insert时,我们更希望是把一个Poco直接传递过去,而不是来new一个匿名函 ...

  4. zoj3822-Domination (概率dp)

    题意: 给你n*m的棋盘,每天选择的一个空的方格放一个棋子,求使棋盘的每行每列都至少有一个棋子的天数期望. 分析: 先想状态,要使每行每列都至少一个,考虑前i行j列,能放得就是i行j列里面的或第i+1 ...

  5. poj 3311 Hie with the Pie

    floyd,旅游问题每个点都要到,可重复,最后回来,dp http://poj.org/problem?id=3311 Hie with the Pie Time Limit: 2000MS   Me ...

  6. HDU-3280 Equal Sum Partitions

    http://acm.hdu.edu.cn/showproblem.php?pid=3280 用了简单的枚举. Equal Sum Partitions Time Limit: 2000/1000 M ...

  7. bug报告-常用词汇中英对照表

  8. ubuntu 下 数学库编译链接时找不到各种数学问题解决方法 can not fon atan 等等

    解决参考 http://askubuntu.com/questions/190246/ld-cannot-find-math-library you should use -lm at the end ...

  9. web服务器分析与设计(一)

    自己写一个简单的服务器. 面向对象分析与设计第一步:获取需求(基于用例) 功能:1,支持html静态网页,2,支持常用HTTP请求,且容易扩展支持不现请求 3,可以发布站点 补充:至于对动态网页等高级 ...

  10. [HIve - LanguageManual] Joins

    Hive Joins Hive Joins Join Syntax Examples MapJoin Restrictions Join Optimization Predicate Pushdown ...