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

去博客园看该题解

题目(传送门)

题意概括

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

题解

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

代码

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

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

  1. POJ3076 Sudoku 舞蹈链 DLX

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的16*16数独,求解. 题解 DLX + 矩阵构建  (两个传送门) 学完这个之后,再 ...

  2. POJ3074 Sudoku 舞蹈链 DLX

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

  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. Linux 两组信号对比(关闭和停止进程信号)

    之前看信号的时候,没有太注意不同信号的对比.今天再次看到的时候,突然感觉对一些信号,非常相似,乃至非常容易混淆.今天周末就抽空总结一下. 一.关闭进程信号 常见的4中关闭进程信号是SIGKILL,SI ...

  2. CentOS 7安装Python3.5

    CentOS 7下安装Python3.5 •安装python3.5可能使用的依赖 yum install openssl-devel bzip2-devel expat-devel gdbm-deve ...

  3. 洛谷P4389 付公主的背包 [生成函数,NTT]

    传送门 同样是回过头来发现不会做了,要加深一下记忆. 思路 只要听说过生成函数的人相信第一眼都可以想到生成函数. 所以我们要求 \[ ans=\prod \sum_n x^{nV}=\prod \fr ...

  4. Codeforces 993E Nikita and Order Statistics [FFT]

    洛谷 Codeforces 思路 一开始想偏想到了DP,后来发现我SB了-- 考虑每个\(a_i<x\)的\(i\),记录它前一个和后一个到它的距离为\(L_i,R_i\),那么就有 \[ an ...

  5. springmvc框架原理分析和简单入门程序

    一.什么是springmvc? 我们知道三层架构的思想,并且如果你知道ssh的话,就会更加透彻的理解这个思想,struts2在web层,spring在中间控制,hibernate在dao层与数据库打交 ...

  6. SVG前戏—让你的View多姿多彩

    什么是SVG SVG的全称是Scalable Vector Graphics,叫可缩放矢量图形.是一种基于可扩展标记语言(XML).它和位图(Bitmap)相对,SVG不会像位图一样因为缩放而让图片质 ...

  7. 树形dp 入门

    今天学了树形dp,发现树形dp就是入门难一些,于是好心的我便立志要发一篇树形dp入门的博客了. 树形dp的概念什么的,相信大家都已经明白,这里就不再多说.直接上例题. 一.常规树形DP P1352 没 ...

  8. popup的简单应用举例(具体在增删改查组件中用到)以及补充的知识点

    一.首先说一下自执行函数 1. 立即执行函数是什么?也就是匿名函数 立即执行函数就是 声明一个匿名函数 马上调用这个匿名函数 2.popup的举例 点击,弹出一个新的窗口.保存完事,页面不刷新数据就返 ...

  9. django rest framework(3)

    目录 一.版本 二.解析器 三.序列化 四.请求数据验证 一.版本 程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取. class ...

  10. dubbo源码之服务发布与注册

    服务端发布流程: dubbo 是基于 spring 配置来实现服务的发布的,对于dubbo 配置文件中看到的<dubbo:service>等标签都是服务发布的重要配置 ,对于这些提供可配置 ...