欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解

题目(传送门)

题意概括

给出一个残缺的16*16数独,求解。

题解

DLX + 矩阵构建  (两个传送门)

学完这个之后,再思考这一题。同样,每个位置每种取值4个信息。

数独共256个格子,每个格子都得填一个数,那么,我们要精确覆盖每一个格子,所以我们首先建立1~256列。

然后还有16行,每行1~16,每行都得精确覆盖,16行,又得建立16*16=256列;

然后还有16列,每列1~16,同理。

然后还有16个4*4的小格子,每个里面1~16,也同理。

那么总共要建立4*256=1024列。

代码

  1. #include <cstring>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstdlib>
  5. #include <cmath>
  6. using namespace std;
  7. const int N=,M=,S=N*+M;
  8. struct DLX{
  9. int n,m,cnt;
  10. int x[S],y[S],L[S],R[S],U[S],D[S];
  11. int C[M],anscnt,ans[N];
  12. void init(int c){
  13. memset(x,,sizeof x),memset(y,,sizeof y);
  14. memset(L,,sizeof L),memset(R,,sizeof R);
  15. memset(U,,sizeof U),memset(D,,sizeof D);
  16. memset(C,,sizeof C),memset(ans,,sizeof ans);
  17. anscnt=,m=c;
  18. for (int i=;i<=m;i++)
  19. L[i]=i-,R[i]=i+,U[i]=D[i]=i;
  20. L[]=m,R[m]=,cnt=m;
  21. }
  22. void link(int i,int j){
  23. cnt++;
  24. x[cnt]=i;
  25. y[cnt]=j;
  26. L[cnt]=cnt-;
  27. R[cnt]=cnt+;
  28. D[cnt]=j;
  29. D[U[j]]=cnt;
  30. U[cnt]=U[j];
  31. U[j]=cnt;
  32. C[j]++;
  33. }
  34. void Delete(int k){
  35. L[R[k]]=L[k];
  36. R[L[k]]=R[k];
  37. for (int i=D[k];i!=k;i=D[i])
  38. for (int j=R[i];j!=i;j=R[j]){
  39. U[D[j]]=U[j];
  40. D[U[j]]=D[j];
  41. C[y[j]]--;
  42. }
  43. }
  44. void Reset(int k){
  45. L[R[k]]=k;
  46. R[L[k]]=k;
  47. for (int i=U[k];i!=k;i=U[i])
  48. for (int j=L[i];j!=i;j=L[j]){
  49. U[D[j]]=j;
  50. D[U[j]]=j;
  51. C[y[j]]++;
  52. }
  53. }
  54. bool solve(){
  55. if (R[]==)
  56. return true;
  57. anscnt++;
  58. int k=R[];
  59. for (int i=R[k];i!=;i=R[i])
  60. if (C[i]<C[k])
  61. k=i;
  62. Delete(k);
  63. for (int i=D[k];i!=k;i=D[i]){
  64. ans[anscnt]=x[i];
  65. for (int j=R[i];j!=i;j=R[j])
  66. Delete(y[j]);
  67. if (solve())
  68. return true;
  69. for (int j=L[i];j!=i;j=L[j])
  70. Reset(y[j]);
  71. }
  72. Reset(k);
  73. anscnt--;
  74. return false;
  75. }
  76. }dlx;
  77. int a[][],x[N],y[N],z[N];
  78. char s[];
  79. int hash(int a,int b,int c){
  80. return a*+b*+c+;
  81. }
  82. int main(){
  83. while (~scanf("%s",s+)){
  84. for (int i=;i<=;i++){
  85. for (int j=;j<=;j++)
  86. if (s[j]=='-')
  87. a[i][j]=;
  88. else
  89. a[i][j]=s[j]-'A'+;
  90. if (i<)
  91. scanf("%s",s+);
  92. }
  93. dlx.init();
  94. int Row=;
  95. for (int i=;i<=;i++)
  96. for (int j=;j<=;j++){
  97. int st,en;
  98. if (a[i][j]==)
  99. st=,en=;
  100. else
  101. st=en=a[i][j];
  102. for (int k=st;k<=en;k++){
  103. Row++;
  104. x[Row]=i,y[Row]=j,z[Row]=k;
  105. int first=dlx.cnt+;
  106. dlx.link(Row,hash(,i-,j-));
  107. dlx.link(Row,hash(,i-,k-));
  108. dlx.link(Row,hash(,j-,k-));
  109. dlx.link(Row,hash(,((i-)/)*+(j-)/,k-));
  110. dlx.L[first]=dlx.cnt;
  111. dlx.R[dlx.cnt]=first;
  112. }
  113. }
  114. bool found=dlx.solve();
  115. for (int i=;i<=dlx.anscnt;i++)
  116. a[x[dlx.ans[i]]][y[dlx.ans[i]]]=z[dlx.ans[i]];
  117. for (int i=;i<=;puts(""),i++)
  118. for (int j=;j<=;j++)
  119. printf("%c",a[i][j]+'A'-);
  120. puts("");
  121. }
  122. return ;
  123. }

POJ3076 Sudoku 舞蹈链 DLX的更多相关文章

  1. POJ3074 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求解. 题解 DLX + 矩阵构建  (两个传送门) 代码 #include & ...

  2. POJ2676 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求解.SPJ 题解 DLX + 矩阵构建  (两个传送门) 代码 #includ ...

  3. 舞蹈链 DLX

    欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 舞蹈链是一个非常玄学的东西…… 问题模型 精确覆盖问题:在一个01矩阵中,是否可以选出一些行的集合,使得在这些行的集 ...

  4. [学习笔记] 舞蹈链(DLX)入门

    "在一个全集\(X\)中若干子集的集合为\(S\),精确覆盖(\(\boldsymbol{Exact~Cover}\))是指,\(S\)的子集\(S*\),满足\(X\)中的每一个元素在\( ...

  5. [poj3074]Sudoku(舞蹈链)

    题目链接:http://poj.org/problem?id=3074 舞蹈链精确覆盖的经典题目,一个数独每个位置的要求,可以得到以下四个约束1.每个位置有且只有一个数字2.每个位置的数字在一行只能出 ...

  6. luogu P4929 【模板】舞蹈链 DLX

    LINK:舞蹈链 具体复杂度我也不知道 但是 搜索速度极快. 原因大概是因为 每次检索的时间少 有一定的剪枝. 花了2h大概了解了这个东西 吐槽一下题解根本看不懂 只能理解大概的想法 核心的链表不太懂 ...

  7. Vijos1755 靶形数独 Sudoku NOIP2009 提高组 T4 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的数独,求这个数独中所有的解法中的最大价值. 一个数独解法的价值之和为每个位置所填的数值 ...

  8. P4929-[模板]舞蹈链(DLX)

    正题 题目链接:https://www.luogu.com.cn/problem/P4929 题目大意 \(n*m\)的矩形有\(0/1\),要求选出若干行使得每一列有且仅有一个\(1\). 解题思路 ...

  9. 关于用舞蹈链DLX算法求解数独的解析

    欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 描述 在做DLX算法题中,经常会做到数独类型的题目,那么,如何求解数独类型的题目?其实,学了数独的构建方法,那么DL ...

随机推荐

  1. SQL Server代码段

    1.cast和convert ' as int) -- 123 ') -- 123 select CAST(123.4 as int) -- 123 select CONVERT(int, 123.4 ...

  2. 【原创】大数据基础之Benchmark(2)TPC-DS

    tpc 官方:http://www.tpc.org/ 一 简介 The TPC is a non-profit corporation founded to define transaction pr ...

  3. Netflix正式开源其API网关Zuul 2

    5 月 21 日,Netflix 在其官方博客上宣布正式开源微服务网关组件 Zuul 2.Netflix 公司是微服务界的楷模,他们有大规模生产级微服务的成功应用案例,也开源了相当多的微服务组件(详见 ...

  4. Winform中的TextBox的小技巧

    1  一些常用属性this.textBox5.PasswordChar = '@';  //密码的样式            this.textBox5.UseSystemPasswordChar = ...

  5. Confluence 6 管理协同编辑

    协同编辑能够让项目小组中的协同合作达到下一个高度.这个页面对相关协同编辑中的问题进行了讨论,能够提供给你所有希望了解的内容. 进入 Collaborative editing 页面来获得项目小组是如何 ...

  6. Confluence 6 缓存性能示例

    有关 Confluence 的缓存性能如何设置,让我们看看下面的表: 缓存(Caches) % 使用的缓存(Used) % 有效率(Effectiveness) 对象/大小(Objects/Size) ...

  7. CentOS7图形界面与命令行界面切换(转载)

    在图形界面使用 ctrl+alt+F2切换到dos界面 dos界面 ctrl+alt+F2切换回图形界面 在命令上 输入 init 3 命令 切换到dos界面 输入 init 5命令 切换到图形界面 ...

  8. exec与match方法的区别

    http://www.cnblogs.com/xiehuiqi220/archive/2008/11/05/1327487.html var someText= "web2.0 .net2. ...

  9. java易错题----静态方法的调用

    class A{ public static String s="A.s"; } class B extends A{ public static String s="B ...

  10. 在lnmp环境下,将原来的PHP7.0升级到PHP7.2

    基础环境: 系统:centos6.8   环境:lnmp 停止PHP7.0的版本,在做如下操作: 1.下载php-7.2.6.tar.bz2软件包放在/opt 路径下 mkdir /usr/local ...