首先dfs给每个格子分一个大的区块

其次套板子就a

我一开始直接在选取行的时候填数独,发现超时

我这一行也就4个元素,找到 x <= 81 的列计算元素位置,81 < x <= 162 的列计算是什么数字

这就超时了?

后来还是记录每一行的代表的  行和列 和 数字

选区行的时候记录选取的行

最后矩阵为空的时候  一起填入数独

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. using namespace std;
  5. //精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1
  6. const int MN = ;//最大行数
  7. const int MM = ;//最大列数
  8. const int MNN = 1e5+; //最大点数
  9. int pl;
  10. int anss[][];
  11. struct node
  12. {
  13. int i,j,val;
  14. };
  15. node p[**+];
  16. struct DLX
  17. {
  18. int n, m, si;//n行数m列数si目前有的节点数
  19. //十字链表组成部分
  20. int U[MNN], D[MNN], L[MNN], R[MNN], Row[MNN], Col[MNN];
  21. //第i个结点的U向上指针D下L左R右,所在位置Row行Col列
  22. int H[MN], S[MM]; //记录行的选择情况和列的覆盖情况
  23. int ansd, ans[MN];
  24. int k = ;
  25. void init(int _n, int _m) //初始化空表
  26. {
  27. n = _n;
  28. m = _m;
  29. k = ;
  30. for (int i = ; i <= m; i++) //初始化第一横行(表头)
  31. {
  32. U[i] = D[i] = i; //目前纵向的链是空的
  33. L[i] = i - ;
  34. R[i] = i + ; //横向的连起来
  35. }
  36. R[m] = ; L[] = m;
  37. si = m; //目前用了前0~m个结点
  38. memset(S, , sizeof(S));
  39. memset(H, -, sizeof(H));
  40. }
  41. void link(int r, int c) //插入点(r,c)
  42. {
  43. ++S[Col[++si] = c]; //si++;Col[si]=c;S[c]++;
  44. Row[si] = r;//si该结点的行数为r
  45. D[si] = D[c];//向下指向c的下面的第一个结点
  46. U[D[c]] = si;//c的下面的第一个结点的上面为si
  47. U[si] = c;//si的上面为列指针
  48. D[c] = si;//列指针指向的第一个该列中的元素设为si
  49. if (H[r]<)//如果第r行没有元素
  50. H[r] = L[si] = R[si] = si;
  51. else
  52. {
  53. R[si] = R[H[r]];//si的右边为行指针所指的右边第一个元素
  54. L[R[H[r]]] = si;//行指针所指的右边第一个元素的左侧为si
  55. L[si] = H[r];//si的左侧为行指针
  56. R[H[r]] = si;//行指针的右侧为si
  57. }
  58. }
  59. void rm(int c) //列表中删掉c列
  60. {
  61. L[R[c]] = L[c];//表头操作 //c列头指针的右边的元素的左侧指向c列头指针左边的元素
  62. R[L[c]] = R[c];//c列头指针的左边的元素的右侧指向c列头指针右边的元素
  63. for (int i = D[c]; i != c; i = D[i])//遍历该列的所有元素
  64. for (int j = R[i]; j != i; j = R[j])
  65. {//对于该列的某个元素所在的行进行遍历
  66. U[D[j]] = U[j];//把该元素从其所在列中除去
  67. D[U[j]] = D[j];
  68. --S[Col[j]];//该元素所在的列数目减一
  69. }
  70. }
  71. void resume(int c) //恢复c列
  72. {
  73. for (int i = U[c]; i != c; i = U[i])//枚举该列元素
  74. for (int j = L[i]; j != i; j = L[j])//枚举该列元素所在的行
  75. ++S[Col[U[D[j]] = D[U[j]] = j]];//D[U[j]]=j;U[D[j]]=j;S[Col[j]]++;
  76. L[R[c]] = R[L[c]] = c;//c列头指针左右相连
  77. }
  78. bool dance(int d) //选取了d行
  79. {
  80. if (ansd != - && ansd < d)return ;
  81. if (R[] == )//全部覆盖了
  82. {
  83. k++;
  84. //全覆盖了之后的操作
  85. if(ansd==-)ansd = d;
  86. else if (d < ansd) ansd = d;
  87. /*memcpy(fina,anss,sizeof(anss));
  88. for(int i = 0; i < 9; ++i)
  89. {
  90. for(int j = 0; j < 9; ++j)
  91. printf("%d",anss[i][j]);
  92. printf("\n");
  93. }*/
  94. for(int i = ; i < ansd; ++i)
  95. {
  96. anss[p[ans[i]].i][p[ans[i]].j] = p[ans[i]].val;
  97. }
  98. return ;
  99. }
  100. int c = R[];//表头结点指向的第一个列
  101. for (int i = R[]; i != ; i = R[i])//枚举列头指针
  102. if (S[i]<S[c])//找到列中元素个数最少的
  103. c = i;
  104. rm(c);//将该列删去
  105. for (int i = D[c]; i != c; i = D[i])
  106. {
  107. ans[d] = Row[i];
  108. for (int j = R[i]; j != i; j = R[j])
  109. rm(Col[j]);//将该列的某个元素的行上的元素所在的列都删去
  110. dance(d + );
  111. if(k == ) return ;
  112. for (int j = L[i]; j != i; j = L[j])
  113. resume(Col[j]);
  114.  
  115. }
  116. resume(c);
  117. return ;
  118. }
  119. };
  120. int s[][];
  121. int kua[][];
  122. int arr[][];
  123. int dx[] = {,,,-};
  124. int dy[] = {-,,,};
  125. int fc[] = {,,,};
  126. DLX di;
  127. void dfs(int x,int y,int cnt);
  128. int main()
  129. {
  130. int t,ppap = ;
  131. scanf("%d",&t);
  132. while(ppap <= t)
  133. {
  134. memset(anss,,sizeof(anss));
  135. for(int i = ; i < ; ++i)
  136. {
  137. for(int j = ; j < ; ++j)
  138. {
  139. scanf("%d",s[i]+j);
  140. }
  141. }
  142. int cnt = ;
  143. memset(kua,,sizeof(kua));
  144. for(int i = ; i < ; ++i)
  145. for(int j = ; j < ; ++j)
  146. {
  147. if(kua[i][j] == )
  148. {
  149. kua[i][j] = cnt;
  150. dfs(i,j,cnt++);
  151. }
  152. }
  153. /*
  154. for(int i = 0; i < 9; ++i)
  155. {
  156. for(int j = 0; j < 9; ++j)
  157. printf("%d ",arr[i][j]);
  158. printf("\n");
  159. }
  160. */
  161. //----------------------------
  162. di.init(**,**);
  163. for(int i = ; i < ; ++i)
  164. {
  165. for(int j = ; j < ; ++j)
  166. {
  167. //cout << s[cnt];
  168. if(arr[i][j] == )
  169. {
  170. for(int d = ; d <= ; ++d)
  171. {
  172. di.link(i**+j*+d,i*+j+);
  173. di.link(i**+j*+d,i*+d+);
  174. di.link(i**+j*+d,j*+d+);
  175. di.link(i**+j*+d,(kua[i][j]-)*+d+);
  176. p[i**+j*+d].i = i; p[i**+j*+d].j = j; p[i**+j*+d].val = d;
  177. }
  178. }
  179. else
  180. {
  181. int d = arr[i][j];
  182. di.link(i**+j*+d,i*+j+);
  183. di.link(i**+j*+d,i*+d+);
  184. di.link(i**+j*+d,j*+d+);
  185. di.link(i**+j*+d,(kua[i][j]-)*+d+);
  186. p[i**+j*+d].i = i; p[i**+j*+d].j = j; p[i**+j*+d].val = d;
  187. }
  188. }
  189. }
  190.  
  191. di.ansd = -;
  192. di.dance();
  193. printf("Case %d:\n",ppap++);
  194. if(di.ansd == -)
  195. {
  196. printf("No solution\n");
  197. continue;
  198. }
  199. if(di.k != )
  200. {
  201. printf("Multiple Solutions\n");
  202. continue;
  203. }
  204. /*for(int i = 0; i < 9; ++i)
  205. {
  206. for(int j = 0; j < 9; ++j)
  207. printf("%d",anss[i][j]);
  208. printf("\n");
  209. }*/
  210. for(int i = ; i < ; ++i)
  211. {
  212. for(int j = ; j < ; ++j)
  213. {
  214. printf("%d",anss[i][j]);
  215. }
  216. printf("\n");
  217. }
  218. }
  219. }
  220. void dfs(int x,int y,int cnt)
  221. {
  222. int k = s[x][y];
  223. //cout << x << y << " " << s[x][y]<< endl;
  224. int xx,yy;
  225. for(int i = ; i < ; ++i)
  226. {
  227. xx = x + dx[i];
  228. yy = y + dy[i];
  229. if(k >= fc[i]) {
  230. k-=fc[i];
  231. continue;
  232. }
  233. if(kua[xx][yy] == ){
  234. kua[xx][yy] = cnt;
  235. dfs(xx,yy,cnt);
  236. }
  237. }
  238. arr[x][y] = k;
  239. }

hdu 4069 垃圾数独的更多相关文章

  1. HDU 4069 数独

    好久没做题了,建图搞了好久…… 然后,判是否有多解的时候会把原来的答案覆盖掉…… 这里没注意,弄了一下午…… 代码: #include <iostream> #include <cs ...

  2. HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069 Problem Description Today we play a squiggly sud ...

  3. hdu 4069 福州赛区网络赛I DLC ***

    再遇到一个DLC就刷个专题 #include <stdio.h> #include <string.h> #include <iostream> #include ...

  4. (中等) HDU 4069 Squiggly Sudoku , DLX+精确覆盖。

    Description Today we play a squiggly sudoku, The objective is to fill a 9*9 grid with digits so that ...

  5. [DLX+bfs] hdu 4069 Squiggly Sudoku

    题意: 给你9*9的矩阵.对于每一个数字.能减16代表上面有墙,能减32代表以下有墙. .. 最后剩下的数字是0代表这个位置数要求,不是0代表这个数已知了. 然后通过墙会被数字分成9块. 然后做数独, ...

  6. Dancing Links [Kuangbin带你飞] 模版及题解

    学习资料: http://www.cnblogs.com/grenet/p/3145800.html http://blog.csdn.net/mu399/article/details/762786 ...

  7. Dancing Link专题

    一些链接: http://www.cnblogs.com/-sunshine/p/3358922.html http://www.cnblogs.com/grenet/p/3145800.html 1 ...

  8. KUANGBIN带你飞

    KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题    //201 ...

  9. [kuangbin带你飞]专题1-23题目清单总结

    [kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...

随机推荐

  1. Robot Return to Origin

    There is a robot starting at position (0, 0), the origin, on a 2D plane. Given a sequence of its mov ...

  2. ES6学习笔记(字符串和数值)

    (一)字符串的扩展 1.字符串的遍历 for (let codePoint of 'foo') { console.log(codePoint) } // "f" // " ...

  3. Ubuntu 清除缓存 apt-get命令参数

    整理了Ubuntu Linux操作系统下apt-get命令的详细说明,分享给大家.常用的APT命令参数:apt-cache search package 搜索包apt-cache show packa ...

  4. 138 条 Vim 命令、操作、快捷键全集

    命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filename 打开vim ...

  5. ACM学习之路

     2018-10-18 11:03:00 今天开始踏上实现梦想的道路,希望自己不要懈怠. 坚持做简单的事,坚持下来就会变得不简单.

  6. AS3语法和UNITY C#语法的异同

      AS3 UNITY Sprite a = new Sprite(); trace(a.paent); 此时a.parent为null,还未AddChild到屏幕上, 一般用这个来判断在不在屏幕上 ...

  7. pwnable.kr-passcode-witeup

    进入远端运行, 废话不多说,下载下来分析. 根据提示,编译一下子. 知道问题了. 想象着,输入的值到了passcode1和passcode2的值作为地址的地方,passcode1处刚输入值时,程序终止 ...

  8. vue项目中使用less或者sass的方法

    半年木有更新博客了... 前段时间一直在学习vue,开始记录一下遇到的问题吧 这篇文章主要是总结一下vue中使用less或者sass的方法,以less为例(style.less) 主要是两种 1.对于 ...

  9. 关于jqGrid组件表格无法自适应宽度问题

    今天生成了一个4列的表格,但是无法自适应宽度,使用 $(window).resize(function(){ $(window).unbind("onresize"); $(&qu ...

  10. ListView的BeginUpdate()和EndUpdate()作用[z]

    [z]https://blog.csdn.net/u011108093/article/details/79448060 许多Windows 窗体控件(例如,ListView 和 TreeView 控 ...