题意:解数独

分析:

完整的数独有四个充要条件:

1.每个格子都有填数字

2.每列都有1~9中的每个数字

3.每行都有1~9中的每个数字

4.每个9宫格都有1~9中的每个数字

可以转化成精确覆盖问题。每行表示一个格子的一种填法,1~81列表示这个格子的位置,82~162列表示这是哪一行的什么数字,163~243列表示这是哪一列的什么数字,244~324列表示这是哪一个九宫格里的什么数字。每行都把四个1填入这四个区间里的对应位置。最后求出这个01矩阵的精确覆盖就是解。

在DFS里删除列的顺序为由左往右时TLE了,由右向左却AC,什么原因???

  1. #include <cstdio>
  2. #include <cstring>
  3. int U[],D[],L[],R[],row[],col[],cont[];
  4. int X[],Y[],H[],S[],M,N,sz,ans[][];
  5. bool hashr[][],hashc[][],hashp[][];
  6. void init(int m)
  7. {
  8. for(int i = ;i <= m;i++)
  9. {
  10. U[i] = D[i] = i;
  11. L[i + ] = i;
  12. R[i] = i + ;
  13. S[i] = ;
  14. }
  15. R[m] = ;
  16. L[] = m;
  17. sz = m + ;
  18. }
  19.  
  20. void remove(int c)
  21. {
  22. //删除一整列
  23. R[L[c]] = R[c];
  24. L[R[c]] = L[c];
  25. //删除行
  26. for(int i = D[c];i != c;i = D[i])
  27. {
  28. for(int j = R[i];j != i;j = R[j])
  29. {
  30. D[U[j]] = D[j];
  31. U[D[j]] = U[j];
  32. S[X[j]]--;
  33. }
  34. }
  35. }
  36.  
  37. void resume(int c)
  38. {
  39. //恢复一整列
  40. L[R[c]] = c;
  41. R[L[c]] = c;
  42. //恢复行
  43. for(int i = U[c];i != c;i = U[i])
  44. {
  45. for(int j = L[i];j != i;j = L[j])
  46. {
  47. D[U[j]] = j;
  48. U[D[j]] = j;
  49. S[X[j]]++;
  50. }
  51. }
  52. }
  53.  
  54. void ins(int r,int c)
  55. {
  56. S[c]++;
  57. //纵向插入
  58. D[U[c]] = sz;
  59. U[sz] = U[c];
  60. D[sz] = c;
  61. U[c] = sz;
  62. X[sz] = c;
  63. Y[sz] = r;
  64. //横向插入
  65. if(H[r] == -)
  66. {
  67. H[r] = L[sz] = R[sz] = sz;
  68. }
  69. else
  70. {
  71. R[L[H[r]]] = sz;
  72. L[sz] = L[H[r]];
  73. R[sz] = H[r];
  74. L[H[r]] = sz;
  75. }
  76. sz++;
  77. }
  78.  
  79. bool dfs(int k)
  80. {
  81. if(R[] == )
  82. {
  83. return true;
  84. }
  85. else
  86. {
  87. int m = 0xfffffff,num;
  88. for(int i = R[];i != ;i = R[i])
  89. {
  90. if(S[i] == )
  91. {
  92. return false;
  93. }
  94. if(m > S[i])
  95. {
  96. m = S[i];
  97. num = i;
  98. if(m == )
  99. {
  100. break;
  101. }
  102. }
  103. }
  104. remove(num);
  105. for(int i = D[num];i != num;i = D[i])
  106. {
  107. ans[row[Y[i]]][col[Y[i]]] = cont[Y[i]];
  108. for(int j = R[i];j != i;j = R[j])
  109. {
  110. remove(X[j]);
  111. }
  112. if(dfs(k + ))
  113. {
  114. return true;
  115. }
  116. for(int j = L[i];j != i;j = L[j])//恢复顺序改为由左向右居然慢N倍?!
  117. {
  118. resume(X[j]);
  119. }
  120. }
  121. resume(num);
  122. }
  123. return false;
  124. }
  125.  
  126. int main()
  127. {
  128. char input[];
  129. while(scanf("%s",input),input[] != 'e')
  130. {
  131. memset(hashr,false,sizeof(hashr));
  132. memset(hashc,false,sizeof(hashc));
  133. memset(hashp,false,sizeof(hashp));
  134. for(int i = ;i < ;i++)
  135. {
  136. for(int j = ;j < ;j++)
  137. {
  138. if(input[i * + j] != '.')
  139. {
  140. hashr[i][input[i * + j] - ''] = true;
  141. hashc[j][input[i * + j] - ''] = true;
  142. hashp[i / * + j / ][input[i * + j] - ''] = true;
  143. }
  144. }
  145. }
  146. M = * * ;
  147. N = ;
  148. init(M);
  149. for(int i = ;i < ;i++)
  150. {
  151. for(int j = ;j < ;j++)
  152. {
  153. int k;
  154. if(input[i * + j] != '.')
  155. {
  156. k = input[i * + j] - '';
  157. }
  158. else
  159. {
  160. k = ;
  161. }
  162. if(k != )
  163. {
  164. row[N] = i;
  165. col[N] = j;
  166. cont[N] = k;
  167. H[N] = -;
  168. ins(N,i * + j + );//(i,j)位置已填数字
  169. ins(N, + i * + k);//i行已有k
  170. ins(N, + j * + k);//j列已有k
  171. ins(N++, + (i / * + j / ) * + k);//宫格已有k
  172. }
  173. else
  174. {
  175. for(k = ;k <= ;k++)
  176. {
  177. if(!hashr[i][k] && !hashc[j][k] && !hashp[i / * + j / ][k])
  178. {
  179. row[N] = i;
  180. col[N] = j;
  181. cont[N] = k;
  182. H[N] = -;
  183. ins(N,i * + j + );//(i,j)位置已填数字
  184. ins(N, + i * + k);//i行已有k
  185. ins(N, + j * + k);//j列已有k
  186. ins(N++, + (i / * + j / ) * + k);//宫格已有k
  187. }
  188. }
  189. }
  190. }
  191. }
  192. dfs();
  193. for(int i = ;i < ;i++)
  194. {
  195. for(int j = ;j < ;j++)
  196. {
  197. printf("%d",ans[i][j]);
  198. }
  199. }
  200. printf("\n");
  201. }
  202. return ;
  203. }

poj 3074的更多相关文章

  1. POJ 3074 Sudoku (DLX)

    Sudoku Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  2. 搜索(DLX): POJ 3074 3076 Sudoku

    POJ 3074 : Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller ...

  3. POJ 3074 Sudoku (Dancing Links)

    传送门:http://poj.org/problem?id=3074 DLX 数独的9*9的模板题. 具体建模详见下面这篇论文.其中9*9的数独怎么转化到精确覆盖问题,以及相关矩阵行列的定义都在下文中 ...

  4. 【POJ 3074】 Sudoku

    [题目链接] http://poj.org/problem?id=3074 [算法] 将数独问题转化为精确覆盖问题,用Dancing Links求解 转化方法如下 : 我们知道,在一个数独中 : 1. ...

  5. DLX (poj 3074)

    题目:Sudoku 匪夷所思的方法,匪夷所思的速度!!! https://github.com/ttlast/ACM/blob/master/Dancing%20Link%20DLX/poj%2030 ...

  6. POJ 3074 Sudoku DLX精确覆盖

    DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: ...

  7. POJ 3074 Sudoku (Dacing Links)

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

  8. poj 3074 Sudoku(Dancing Links)

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

  9. (简单) POJ 3074 Sudoku, DLX+精确覆盖。

    Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgr ...

  10. POJ 3074 Sudoku(算竞进阶习题)

    二进制优化+dfs 话说这题数据中真的丧心病狂..不加inline还过不去.. 因为不会DLX只好用二进制来优化了...万万没想到还是低空飘过 我们在行.列.格分别用一个9位二进制常数来记录什么数能放 ...

随机推荐

  1. mysql之distinct

    记录一下这几天看mysql必知必会的小知识点: 关于mysql查询不同的行 比如记录表中 查询有多少个城市 可能查出很多城市 可以用distinct 来解决这个问题 SELECT DISTINCT c ...

  2. May Challenge 2019 Division 2 水题讲解

    Reduce to One 这题其实蛮水的? 题意就是说: 给定一个 1~n 的序列,每次挑两个数 x y 合并,合并值为 \(x+y+xy\) ,然后求不断合并最后剩下的一个的最大值 随便搞搞发现答 ...

  3. video 能播放声音不能播放视频,黑屏

    与视频编码格式有关,mp4的视频编码有三种:MPEG4(DivX),MPEG4(Xvid),AVC(H264). 浏览器播放视频的支持有限,MP4格式的视频只支持h.264的视频: 视频编码: AVC ...

  4. [Usaco2018 Open]Talent Show

    Description FarmerJohn要带着他的N头奶牛,方便起见编号为1-N,到农业展览会上去,参加每年的达牛秀!他的第i头奶牛重量为wi,才艺水平为ti,两者都是整数.在到达时,Farmer ...

  5. Light 1289 - LCM from 1 to n (位图标记+素数筛选)

    题目链接: http://www.lightoj.com/volume_showproblem.php?problem=1289 题目描述: 给出一个n,求出lcm(1,2,3......n)为多少? ...

  6. Android 性能优化(23)*性能工具之「Heap Viewer, Memory Monitor, Allocation Tracker」Memory Profilers

    Memory Profilers In this document Memory Monitor Heap Viewer Allocation Tracker You should also read ...

  7. pyCharm最新激活码(2018)

    1.修改hosts文件: 添加下面一行到hosts文件,目的是屏蔽掉Pycharm对激活码的验证 0.0.0.0 account.jetbrains.com windwos系统hosts文件路径为:C ...

  8. CSS动画持续汇总中

    一:向上的动态箭头------------------http://www.5599.com/88lz/up_direct.html

  9. 喜欢Swift编程语言的人主要是初学者?

    一早一起来,朋友圈除了被苹果发布会刷屏外,还漫天散布着一条类似的招聘消息:“招聘iOS程序员,要求拥有5年的Swift开发经验,有狼性,待遇月薪20K+,专车接送.” 随后身边的朋友很快就开始调侃:& ...

  10. PHP安装yaf在ubuntu下面的问题解决

    1.在执行make的时候出现如下错误: In file included from /root/yaf-2.1.2/yaf_router.c:28: /usr/include/php/ext/pcre ...