题目大意:

16*16的数独。

思路分析:

多说无益.

想说的就是dancing links 的行是依照

第一行第一列填 1

第一行第二列填 2

……

第一行第十五列填15

第一行第二列填 1

……

第二行。。。。

列的纺织则是

第一行放1,第一行放2,。。第十六行放16.。。第一列放1.。第一列放2.。。第十六列放16.。第一块区域放1 。。。。然后在最后81位就是放自己的位置,准确的说就是 r*m+c。

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cstring>
  5. #define maxn 16*16*16*16*16*4+5
  6. #define inf 0x3f3f3f3f
  7. using namespace std;
  8.  
  9. int n=16*16*9,m=16*16*4,p;
  10. int map[16*16*16+5][16*16*4+5];
  11. int L[maxn],R[maxn],D[maxn],U[maxn],S[maxn],O[maxn],col[maxn],row[maxn],head,cnt;
  12. int num;
  13.  
  14. void dancing_links_init()
  15. {
  16. head=0;
  17. memset(S,0,sizeof S);
  18. for(int i=head;i<=m;i++)
  19. {
  20. R[i]=(i+1)%(m+1);
  21. L[i]=(i-1+m+1)%(m+1);
  22. U[i]=D[i]=i;
  23. }
  24. cnt=m+1;
  25. for(int i=1;i<=n;i++)
  26. {
  27. int rowh=-1;
  28. for(int j=1;j<=m;j++)
  29. {
  30. if(map[i][j])
  31. {
  32. S[j]++;
  33. U[cnt]=U[j];
  34. D[U[j]]=cnt;
  35. U[j]=cnt;
  36. D[cnt]=j;
  37. row[cnt]=i;
  38. col[cnt]=j;
  39. if(rowh==-1)
  40. {
  41. L[cnt]=R[cnt]=cnt;
  42. rowh=cnt;
  43. }
  44. else
  45. {
  46. L[cnt]=L[rowh];
  47. R[L[rowh]]=cnt;
  48. R[cnt]=rowh;
  49. L[rowh]=cnt;
  50. }
  51. cnt++;
  52. }
  53. }
  54. }
  55. }
  56. void Remove(const int &c)
  57. {
  58. L[R[c]]=L[c];
  59. R[L[c]]=R[c];
  60. for(int i=D[c];i!=c;i=D[i])
  61. {
  62. for(int j=R[i];j!=i;j=R[j])
  63. {
  64. U[D[j]]=U[j];
  65. D[U[j]]=D[j];
  66. --S[col[j]];
  67. }
  68. }
  69. }
  70. void Resume(const int &c)
  71. {
  72. for(int i=U[c];i!=c;i=U[i])
  73. {
  74. for(int j=L[i];j!=i;j=L[j])
  75. {
  76. ++S[col[j]];
  77. U[D[j]]=j;
  78. D[U[j]]=j;
  79. }
  80. }
  81. L[R[c]]=c;
  82. R[L[c]]=c;
  83. }
  84. bool dfs(const int &k)//可行解
  85. {
  86. if(head==R[head])
  87. {
  88. sort(O,O+256);
  89. for(int i=0;i<256;i++)
  90. {
  91. printf("%c",O[i]-i*16+'A'-1);
  92. if(i%16==15)puts("");
  93. }
  94. puts("");
  95. return true;
  96. }
  97. int mx=inf,cur=0;
  98. for(int t=R[head];t!=head;t=R[t])
  99. {
  100. if(S[t]<mx)
  101. {
  102. mx=S[t];
  103. cur=t;
  104. }
  105. }
  106. Remove(cur);//依据開始的时候的推断条件,能够知道是一列一列的选择
  107. for(int i=D[cur];i!=cur;i=D[i])//这里就是先选择列
  108. {//然后去选择删除哪一行是覆盖了这列的
  109. O[k]=row[i];
  110. for(int j=R[i];j!=i;j=R[j])
  111. {
  112. Remove(col[j]);
  113. }
  114. if(dfs(k+1))return true;
  115. for(int j=L[i];j!=i;j=L[j])
  116. {
  117. Resume(col[j]);
  118. }
  119. }
  120. Resume(cur);
  121. return false;
  122. }
  123. /*
  124. void dfs(const int &k)//最优解
  125. {
  126. if(R[head]==head)
  127. {
  128. if(k<num)num=k;
  129. return;
  130. }
  131. if(k>=num)return;
  132. int mx=inf,cur=0;
  133. for(int t=R[head];t!=head;t=R[t])
  134. {
  135. if(S[t]<mx)
  136. {
  137. mx=S[t];
  138. cur=t;
  139. }
  140. }
  141. Remove(cur);
  142. for(int i=D[cur];i!=cur;i=D[i])
  143. {
  144. for(int j=R[i];j!=i;j=R[j])
  145. {
  146. Remove(col[j]);
  147. }
  148. dfs(k+1);
  149. for(int j=L[i];j!=i;j=L[j])
  150. {
  151. Resume(col[j]);
  152. }
  153. }
  154. Resume(cur);
  155. }
  156. */
  157. char tmp[16][1111];
  158. char str[1111];
  159. int main()
  160. {
  161. while(scanf("%s",tmp[0])!=EOF)
  162. {
  163. for(int i=1;i<16;i++)scanf("%s",tmp[i]);
  164. int cnt=0;
  165. for(int i=0;i<16;i++)
  166. for(int j=0;j<16;j++)
  167. str[cnt++]=tmp[i][j];
  168.  
  169. memset(map,0,sizeof map);
  170. int len=cnt;
  171. for(int i=0;i<len;i++)
  172. {
  173. int r=i/16;
  174. int c=i-r*16;
  175. int base=(r*16+c)*16;
  176.  
  177. if(str[i]=='-')
  178. {
  179. for(int k=1;k<=16;k++)
  180. {
  181. map[base+k][r*16+k]=1;
  182. map[base+k][256+c*16+k]=1;
  183. map[base+k][256+256+16*(4*(r/4)+(c/4))+k]=1;
  184. map[base+k][256*3+r*16+c+1]=1;
  185. }
  186. }
  187. else
  188. {
  189. int k=str[i]-'A'+1;
  190. map[base+k][r*16+k]=1;
  191. map[base+k][256+c*16+k]=1;
  192. map[base+k][256+256+16*(4*(r/4)+(c/4))+k]=1;
  193. map[base+k][256+256+256+r*16+c+1]=1;
  194. }
  195. }
  196. dancing_links_init();
  197. dfs(0);
  198. }
  199. return 0;
  200. }

POJ 3076 Sudoku (dancing links)的更多相关文章

  1. poj 3074 Sudoku(Dancing Links)

    Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8152   Accepted: 2862 Descriptio ...

  2. POJ3074 Sudoku —— Dancing Links 精确覆盖

    题目链接:http://poj.org/problem?id=3074 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissio ...

  3. (简单) POJ 3076 Sudoku , DLX+精确覆盖。

    Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...

  4. POJ 3074 Sudoku (Dacing Links)

    推荐一个写数独很好的博客:http://www.cnblogs.com/grenet/p/3163550.html 主要是把九宫格里的元素换到矩阵里面再求解dancing links 网上找的一模版 ...

  5. POJ 3076 Sudoku DLX精确覆盖

    DLX精确覆盖模具称号..... Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 4416   Accepte ...

  6. POJ 3076 Sudoku

    3076 思路: dfs + 剪枝 首先,如果这个位置只能填一种字母,那就直接填 其次,如果对于每一种字母,如果某一列或者某一行或者某一块只能填它,那就填它 然后,对于某个位置如果不能填字母了,或者某 ...

  7. POJ 3076 SUKODU [Dangcing Links DLX精准覆盖]

    和3074仅仅有数目的不同,3074是9×9.本来想直接用3074的.然后MLE,,,就差那么20M的空间,,. 从这里学习到了解法: http://www.cnblogs.com/ylfdrib/a ...

  8. HDU 3111 Sudoku ( Dancing Links 精确覆盖模型 )

    推荐两篇学DLX的博文: http://bbs.9ria.com/thread-130295-1-1.html(这篇对DLX的工作过程演示的很详细) http://yzmduncan.iteye.co ...

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

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

随机推荐

  1. BitHacks--位操作技巧

    ---------------------------------------------------------------------------------------------------- ...

  2. c++ split模板实现

    模板实现,重载+6: template<typename _Elem, typename _Fty> inline void split(const _Elem* s, const _El ...

  3. android 打包 /${zipalign}&quot; error=2, No such file or directory

    当我更新完android L proview之后我的打包出问题了,报错/${zipalign}" error=2, No such file or directory 排查了一下午才知道 近 ...

  4. Spring 从零開始-05

    最终能到Spring的AOP编程了,AOP的概念特别的多.所以须要你在開始之前有点了解,然后通过代码慢慢学习! - 切面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象.事务管 ...

  5. JQuery AJAX Demo

    JQuery AJAX Demo APP发展集团:347072638(HTML5,APP) 1.先看一个JQuery AJAX Demo HTML端: <!DOCTYPE html PUBLIC ...

  6. linux命令:scp

    有时候ftp被禁用了, 就用scp替代; 命令行: scp from to_user@to_ip:dir_to/file_name 执行该命令之后,按照提示输入to_host的登陆密码即可. scp ...

  7. ABAP 向上取整和向下取整 CEIL & FLOOR

    下面是一段关于CEIL 和 FLOOR 的代码 DATA:a TYPE mseg-menge, b TYPE mseg-menge, c TYPE mseg-menge. a = '1.36'. b ...

  8. Ubuntu_文件夹名字转化成英文

    打开终端命令行输入: export LANG=en_US xdg-user-dirs-gtk-update 之后重启,就看到中文的文件夹变成英文的了 想要换回中文的输入: export LANG=zh ...

  9. HDU 4893 Wow! Such Sequence!(2014年多校联合 第三场 G)(线段树)

    磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add  把d加到第k个数上去2 ...

  10. C++运算符重载的方法

    运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算.也就是说,运算符重载是通过定义函数实现的. 运算符重载实质上是函数的重载 重载运算符的函 ...