题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069

Problem Description
Today we play a squiggly sudoku, The objective is to fill a 9*9 grid with digits so that each column, each row, and each of the nine Connecting-sub-grids that compose the grid contains all of the digits from 1 to 9.
Left figure is the puzzle and right figure is one solution.

Now, give you the information of the puzzle, please tell me is there no solution or multiple solution or one solution.
 
Input
The first line is a number T(1<=T<=2500), represents the number of case. The next T blocks follow each indicates a case.
Each case contains nine lines, Each line contains nine integers.
Each module number tells the information of the gird and is the sum of up to five integers:
0~9: '0' means this gird is empty, '1' - '9' means the gird is already filled in.
16: wall to the up
32: wall to the right
64: wall to the down
128: wall to the left
I promise there must be nine Connecting-sub-grids, and each contains nine girds.
 
Output
For each case, if there are Multiple Solutions or no solution just output "Multiple Solutions" or "No solution". Else output the exclusive solution.(as shown in the sample output)

题目大意:给一个不规则的9阶数独,问是否有唯一解,是则输出。

思路:先DFS一下,找出每个格子对应的块号,再套DLX的模板。

代码(1203MS):

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. #include <vector>
  6. using namespace std;
  7. typedef long long LL;
  8.  
  9. const int MAXN = ;
  10. const int MAXC = * * + ;
  11. const int MAXR = * * + ;
  12. const int MAXP = MAXR * + MAXC;
  13.  
  14. struct DLX {
  15. int sz;
  16. int sum[MAXC];
  17. int row[MAXP], col[MAXP];
  18. int left[MAXP], right[MAXP], up[MAXP], down[MAXP];
  19. int ansd, ans[MAXR], anscnt;
  20.  
  21. void init(int n) {
  22. for(int i = ; i <= n; ++i) {
  23. up[i] = down[i] = i;
  24. left[i] = i - ; right[i] = i + ;
  25. }
  26. left[] = n; right[n] = ;
  27. sz = n + ;
  28. memset(sum, , sizeof(sum));
  29. }
  30.  
  31. void add_row(int r, vector<int> &func) {
  32. int first = sz;
  33. for(size_t i = ; i < func.size(); ++i) {
  34. int c = func[i];
  35. left[sz] = sz - ; right[sz] = sz + ; up[sz] = up[c]; down[sz] = c;
  36. down[up[c]] = sz; up[c] = sz;
  37. row[sz] = r; col[sz] = c;
  38. ++sum[c], ++sz;
  39. }
  40. left[first] = sz - ; right[sz - ] = first;
  41. }
  42.  
  43. void remove(int c) {
  44. left[right[c]] = left[c];
  45. right[left[c]] = right[c];
  46. for(int i = down[c]; i != c; i = down[i]) {
  47. for(int j = right[i]; j != i; j = right[j])
  48. up[down[j]] = up[j], down[up[j]] = down[j], --sum[col[j]];
  49. }
  50. }
  51.  
  52. void restore(int c) {
  53. for(int i = up[c]; i != c; i = up[i]) {
  54. for(int j = left[i]; j != i; j = left[j])
  55. up[down[j]] = j, down[up[j]] = j, ++sum[col[j]];
  56. }
  57. left[right[c]] = c;
  58. right[left[c]] = c;
  59. }
  60.  
  61. bool dfs(int d) {
  62. if(!right[]) {
  63. ansd = d;
  64. return ++anscnt == ;
  65. }
  66. int c = right[];
  67. for(int i = right[]; i != ; i = right[i]) if(sum[i] < sum[c]) c = i;
  68. remove(c);
  69. for(int i = down[c]; i != c; i = down[i]) {
  70. if(!anscnt) ans[d] = row[i];
  71. for(int j = right[i]; j != i; j = right[j]) remove(col[j]);
  72. if(dfs(d + )) return true;
  73. for(int j = left[i]; j != i; j = left[j]) restore(col[j]);
  74. }
  75. restore(c);
  76. return false;
  77. }
  78.  
  79. int solve(vector<int> &v) {
  80. v.clear();
  81. anscnt = ;
  82. dfs();
  83. if(anscnt == ) for(int i = ; i < ansd; ++i) v.push_back(ans[i]);
  84. return anscnt;
  85. }
  86. } solver;
  87.  
  88. const int SLOT = ;
  89. const int ROW = ;
  90. const int COL = ;
  91. const int SUB = ;
  92.  
  93. int fr[] = {-, , , };
  94. int fc[] = {, , , -};
  95. int fp[] = {, , , };
  96.  
  97. int mat[MAXN][MAXN];
  98. int val[MAXN][MAXN], cnt;
  99. int T, n = ;
  100.  
  101. bool in_n(int x) {
  102. return <= x && x < n;
  103. }
  104.  
  105. void dfs(int r, int c, int p) {
  106. val[r][c] = p;
  107. for(int i = ; i < ; ++i) {
  108. int nr = r + fr[i], nc = c + fc[i];
  109. if(in_n(nr) && in_n(nc) && ((fp[i] & mat[r][c]) == ) && !val[nr][nc])
  110. dfs(nr, nc, p);
  111. }
  112. }
  113.  
  114. void print(int mat[MAXN][MAXN]) {
  115. for(int i = ; i < n; ++i) {
  116. for(int j = ; j < n; ++j) printf("%d", mat[i][j]);
  117. puts("");
  118. }
  119. }
  120.  
  121. int encode(int a, int b, int c) {
  122. return a * + b * + c + ;
  123. }
  124.  
  125. void decode(int code, int &a, int &b, int &c) {
  126. --code;
  127. c = code % ; code /= ;
  128. b = code % ; code /= ;
  129. a = code;
  130. }
  131.  
  132. int main() {
  133. scanf("%d", &T);
  134. for(int kase = ; kase <= T; ++kase) {
  135. for(int i = ; i < n; ++i)
  136. for(int j = ; j < n; ++j) scanf("%d", &mat[i][j]);
  137. memset(val, , sizeof(val));
  138. cnt = ;
  139. for(int i = ; i < n; ++i)
  140. for(int j = ; j < n; ++j) if(!val[i][j]) dfs(i, j, ++cnt);
  141. printf("Case %d:\n", kase);
  142. //print(val);
  143. solver.init( * * );
  144. for(int r = ; r < n; ++r)
  145. for(int c = ; c < n; ++c)
  146. for(int i = ; i < ; ++i) mat[r][c] &= ~fp[i];
  147. //print(mat);
  148. for(int r = ; r < n; ++r) for(int c = ; c < n; ++c) for(int v = ; v < n; ++v) {
  149. if(!mat[r][c] || mat[r][c] == + v) {
  150. vector<int> func;
  151. func.push_back(encode(SLOT, r, c));
  152. func.push_back(encode(ROW, r, v));
  153. func.push_back(encode(COL, c, v));
  154. func.push_back(encode(SUB, val[r][c] - , v));
  155. solver.add_row(encode(r, c, v), func);
  156. }
  157. }
  158. vector<int> ans;
  159. int res = solver.solve(ans);
  160. if(res == ) puts("No solution");
  161. if(res == ) {
  162. int r, c, v;
  163. for(size_t i = ; i < ans.size(); ++i) {
  164. decode(ans[i], r, c, v);
  165. mat[r][c] = + v;
  166. }
  167. print(mat);
  168. }
  169. if(res == ) puts("Multiple Solutions");
  170. }
  171. }

HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)的更多相关文章

  1. HDU 4064 Carcassonne(插头DP)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4064 Problem Description Carcassonne is a tile-based ...

  2. HDU 4063 Aircraft(计算几何)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4063 Description You are playing a flying game. In th ...

  3. HDU 4031 Attack(离线+线段树)(The 36th ACM/ICPC Asia Regional Chengdu Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4031 Problem Description Today is the 10th Annual of ...

  4. HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)

    Barricade Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  5. (并查集)Travel -- hdu -- 5441(2015 ACM/ICPC Asia Regional Changchun Online )

    http://acm.hdu.edu.cn/showproblem.php?pid=5441 Travel Time Limit: 1500/1000 MS (Java/Others)    Memo ...

  6. (二叉树)Elven Postman -- HDU -- 54444(2015 ACM/ICPC Asia Regional Changchun Online)

    http://acm.hdu.edu.cn/showproblem.php?pid=5444 Elven Postman Time Limit: 1500/1000 MS (Java/Others)  ...

  7. 2016 ACM/ICPC Asia Regional Qingdao Online(2016ACM青岛网络赛部分题解)

    2016 ACM/ICPC Asia Regional Qingdao Online(部分题解) 5878---I Count Two Three http://acm.hdu.edu.cn/show ...

  8. hdu 5868 2016 ACM/ICPC Asia Regional Dalian Online 1001 (burnside引理 polya定理)

    Different Circle Permutation Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K ...

  9. HDU 5876 Sparse Graph 【补图最短路 BFS】(2016 ACM/ICPC Asia Regional Dalian Online)

    Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)To ...

随机推荐

  1. c语言学习感想

    接触c语言已经2个多月了,在这段期间按时的完成了作业,上课能够较好的听讲,因此我获得了老师奖励的小黄衫. 同时,希望自己能够学好c语言! 学习感受与心得 因为兴趣,选择了计算机这专业,我从遥远的南方来 ...

  2. WeakHashMap 理解笔记

    An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. M ...

  3. Cocos2d-JS cc.DrawNode用法

    app.js var HelloWorldLayer = cc.Layer.extend({ sprite:null, ctor:function () { ///////////////////// ...

  4. SQL 2008 RAISERROR语法在SQL 2012/2014不兼容问题

    原文 旧的RAISERROR语法在SQL 2012不兼容问题 raiserror 写法: SQL 2008: raiserror 55030 'text error' SQL 2012: raiser ...

  5. python StringIO

    模块是用类编写的,只有一个StringIO类,所以它的可用方法都在类中. 此类中的大部分函数都与对文件的操作方法类似. 例: 复制代码 代码如下: #coding=gbk   import Strin ...

  6. [LeetCode]题解(python):086 - Partition List

    题目来源 https://leetcode.com/problems/partition-list/ Given a linked list and a value x, partition it s ...

  7. NSUserDefaults的小封装

    //保存 -(void)saveToUserDefaults:(NSString*)tosaveedString withKey:(NSString *)tosaveedKey {  NSUserDe ...

  8. php图片处理函数自定义画图和引入图片

    <?php //创建画布,就是画画的位置 imagecreate() //为图像分配颜色 imagecolorallocate() 可以把颜色填充到区域中,不能直接填充画布? //区域填充 bo ...

  9. APICloud十一月线下活动(杭州、上海)

    阿里云创业大学 ——APICloud/银杏谷移动课堂[杭州站] 时间:2015年11月28日13:30-16:30 地点:文三路华星时代广场A座3楼银杏谷1024孵化器 主办:APICloud.阿里云 ...

  10. Ubuntu下virtualbox nat网络模式下 实现宿主机访问虚拟机

    参考原文(在windows环境下):http://hi.baidu.com/george_gly/item/5183b76e5a79e49ac5d2498b nat网络模式下,虚拟机可以访问外网.访问 ...