HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)...
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069
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.
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.
题目大意:给一个不规则的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; 10 const int MAXC = 9 * 9 * 4 + 10; 11 const int MAXR = 9 * 9 * 9 + 10; 12 const int MAXP = MAXR * 4 + 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 = 0; i <= n; ++i) { 23 up[i] = down[i] = i; 24 left[i] = i - 1; right[i] = i + 1; 25 } 26 left[0] = n; right[n] = 0; 27 sz = n + 1; 28 memset(sum, 0, sizeof(sum)); 29 } 30 31 void add_row(int r, vector<int> &func) { 32 int first = sz; 33 for(size_t i = 0; i < func.size(); ++i) { 34 int c = func[i]; 35 left[sz] = sz - 1; right[sz] = sz + 1; 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 - 1; right[sz - 1] = 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[0]) { 63 ansd = d; 64 return ++anscnt == 2; 65 } 66 int c = right[0]; 67 for(int i = right[0]; i != 0; 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 + 1)) 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 = 0; 82 dfs(0); 83 if(anscnt == 1) for(int i = 0; i < ansd; ++i) v.push_back(ans[i]); 84 return anscnt; 85 } 86 } solver; 87 88 const int SLOT = 0; 89 const int ROW = 1; 90 const int COL = 2; 91 const int SUB = 3; 92 93 int fr[] = {-1, 0, 1, 0}; 94 int fc[] = {0, 1, 0, -1}; 95 int fp[] = {16, 32, 64, 128}; 96 97 int mat[MAXN][MAXN]; 98 int val[MAXN][MAXN], cnt; 99 int T, n = 9; 100 101 bool in_n(int x) { 102 return 0 <= x && x < n; 103 } 104 105 void dfs(int r, int c, int p) { 106 val[r][c] = p; 107 for(int i = 0; i < 4; ++i) { 108 int nr = r + fr[i], nc = c + fc[i]; 109 if(in_n(nr) && in_n(nc) && ((fp[i] & mat[r][c]) == 0) && !val[nr][nc]) 110 dfs(nr, nc, p); 111 } 112 } 113 114 void print(int mat[MAXN][MAXN]) { 115 for(int i = 0; i < n; ++i) { 116 for(int j = 0; 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 * 81 + b * 9 + c + 1; 123 } 124 125 void decode(int code, int &a, int &b, int &c) { 126 --code; 127 c = code % 9; code /= 9; 128 b = code % 9; code /= 9; 129 a = code; 130 } 131 132 int main() { 133 scanf("%d", &T); 134 for(int kase = 1; kase <= T; ++kase) { 135 for(int i = 0; i < n; ++i) 136 for(int j = 0; j < n; ++j) scanf("%d", &mat[i][j]); 137 memset(val, 0, sizeof(val)); 138 cnt = 0; 139 for(int i = 0; i < n; ++i) 140 for(int j = 0; j < n; ++j) if(!val[i][j]) dfs(i, j, ++cnt); 141 printf("Case %d:\n", kase); 142 //print(val); 143 solver.init(9 * 9 * 4); 144 for(int r = 0; r < n; ++r) 145 for(int c = 0; c < n; ++c) 146 for(int i = 0; i < 4; ++i) mat[r][c] &= ~fp[i]; 147 //print(mat); 148 for(int r = 0; r < n; ++r) for(int c = 0; c < n; ++c) for(int v = 0; v < n; ++v) { 149 if(!mat[r][c] || mat[r][c] == 1 + 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] - 1, 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 == 0) puts("No solution"); 161 if(res == 1) { 162 int r, c, v; 163 for(size_t i = 0; i < ans.size(); ++i) { 164 decode(ans[i], r, c, v); 165 mat[r][c] = 1 + v; 166 } 167 print(mat); 168 } 169 if(res == 2) puts("Multiple Solutions"); 170 } 171 }
View Code
转载于:https://www.cnblogs.com/oyking/p/3947139.html
HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)...相关推荐
- HDU 4069 Squiggly Sudoku 【DLX+BFS】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069 ★这题一开始题都看不懂,后来发现还是挺有意思的 题意: 给你一个9x9的矩阵, 矩阵里面有一些墙 ...
- HDU 4069 Squiggly Sudoku Dancing-Links(DLX)+Floodfill
题目大意:..还是数独,不同的是原先的九宫格约束条件变为了给定的任意形状... 我们跑一遍floodfill 得出每一个格子属于哪一个形状 然后就是裸的数独了 这题T<=2500 绝对不能开动态 ...
- HDU 6194 String String String (后缀数组+线段树, 2017 ACM/ICPC Asia Regional Shenyang Online)
Problem 求字符串 S 中严格出现 k 次的子串个数 k≥1k\ge 1 |S|≤105|S|\le 10^5 ∑|S|≤2×106\sum |S| \le 2\times 10^6 Idea ...
- HDU - 6208 The Dominator of Strings n次KMP 2017 ACM/ICPC Asia Regional Qingdao Online
找到最长串 然后进行n次KMP #include <iostream> #include <cstdio> #include <cstdlib> #include ...
- HDU 4069 Squiggly Sudoku DLX 精确覆盖
题意: 数独问题,给你9个连通块,每个连通块有9个位置. 现在已经有一些数字在上面,让你在空的位置上放数字. 问你是否存在方案,使得每个连通块包含1~9,并且每行每列都有1~9的数字. 输出结果参照样 ...
- [DLX+bfs] hdu 4069 Squiggly Sudoku
题意: 给你9*9的矩阵.对于每个数字,能减16代表上面有墙,能减32代表下面有墙... 最后剩下的数字是0代表这个位置数要求,不是0代表这个数已知了. 然后通过墙会被数字分成9块. 然后做数独,这里 ...
- HDU 4069 Squiggly Sudoku DLX
这是昨天周赛的题,我竟然不会怎么判断多解,后来一google,卧槽,我想复杂了......直接看能搜出来几次就行了. 这题就是个变形,先floodfill一下,然后就是模板了 然后发现比大华的快了好几 ...
- hdu 5444 Elven Postman(根据先序遍历和中序遍历求后序遍历)2015 ACM/ICPC Asia Regional Changchun Online...
很坑的一道题,读了半天才读懂题,手忙脚乱的写完(套上模板+修改模板),然后RE到死-- 题意: 题面上告诉了我们这是一棵二叉树,然后告诉了我们它的先序遍历,然后,没了--没了! 反复读题,终于在偶然间 ...
- HDU 5468 Puzzled Elena(2015 ACM/ICPC Asia Regional Shanghai Online)
题目大意 这道题要求出每个节点与其子树节点中有多少个节点互质,题目是这样,但是如果你认为真的是这样那就错了,因为有可能根节点是1,那么1与本身也是互质的!!其实我真的搞不懂,说好了与子树互质为什么就把 ...
最新文章
- NeurIPS 2021 | 寻MixTraining: 一种全新的物体检测训练范式
- 004_URL 路由 - 对磁盘文件的请求进行路由
- .NET中书写XML的一种简单方法
- java 贝塞尔_java贝塞尔曲线翻页效果
- oracle删除分区空间,Oracle 11g维护分区(三)——Dropping Partitions
- 我在河南安阳拍摄的一个山村小孩儿
- Visual Studio的Web Performance Test提取规则详解(1)
- python canopen_Python canopener包_程序模块 - PyPI - Python中文网
- centos6安装python_如何在CentOS6上安装Python2.7和Python3.3
- 计算机视觉基础:图像处理Task01-图像插值算法
- File类和各种io类会不会自动创建文件
- Visual Studio 远程调试设置
- 深度剖析 C++ 对象池自动回收技术实现
- Servlet原理:
- 两款个人知识库管理软件下载
- iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码
- 操作系统 文件索引结构
- 使用mysqladmin检测MySQL运行状态的教程
- CAcls命令在提权中的使用
- 随想,产品思维和开发思维