题目链接: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;
 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)...相关推荐

  1. HDU 4069 Squiggly Sudoku 【DLX+BFS】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069 ★这题一开始题都看不懂,后来发现还是挺有意思的 题意: 给你一个9x9的矩阵, 矩阵里面有一些墙 ...

  2. HDU 4069 Squiggly Sudoku Dancing-Links(DLX)+Floodfill

    题目大意:..还是数独,不同的是原先的九宫格约束条件变为了给定的任意形状... 我们跑一遍floodfill 得出每一个格子属于哪一个形状 然后就是裸的数独了 这题T<=2500 绝对不能开动态 ...

  3. 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 ...

  4. HDU - 6208 The Dominator of Strings n次KMP 2017 ACM/ICPC Asia Regional Qingdao Online

    找到最长串 然后进行n次KMP #include <iostream> #include <cstdio> #include <cstdlib> #include ...

  5. HDU 4069 Squiggly Sudoku DLX 精确覆盖

    题意: 数独问题,给你9个连通块,每个连通块有9个位置. 现在已经有一些数字在上面,让你在空的位置上放数字. 问你是否存在方案,使得每个连通块包含1~9,并且每行每列都有1~9的数字. 输出结果参照样 ...

  6. [DLX+bfs] hdu 4069 Squiggly Sudoku

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

  7. HDU 4069 Squiggly Sudoku DLX

    这是昨天周赛的题,我竟然不会怎么判断多解,后来一google,卧槽,我想复杂了......直接看能搜出来几次就行了. 这题就是个变形,先floodfill一下,然后就是模板了 然后发现比大华的快了好几 ...

  8. hdu 5444 Elven Postman(根据先序遍历和中序遍历求后序遍历)2015 ACM/ICPC Asia Regional Changchun Online...

    很坑的一道题,读了半天才读懂题,手忙脚乱的写完(套上模板+修改模板),然后RE到死-- 题意: 题面上告诉了我们这是一棵二叉树,然后告诉了我们它的先序遍历,然后,没了--没了! 反复读题,终于在偶然间 ...

  9. HDU 5468 Puzzled Elena(2015 ACM/ICPC Asia Regional Shanghai Online)

    题目大意 这道题要求出每个节点与其子树节点中有多少个节点互质,题目是这样,但是如果你认为真的是这样那就错了,因为有可能根节点是1,那么1与本身也是互质的!!其实我真的搞不懂,说好了与子树互质为什么就把 ...

最新文章

  1. NeurIPS 2021 | 寻MixTraining: 一种全新的物体检测训练范式
  2. 004_URL 路由 - 对磁盘文件的请求进行路由
  3. .NET中书写XML的一种简单方法
  4. java 贝塞尔_java贝塞尔曲线翻页效果
  5. oracle删除分区空间,Oracle 11g维护分区(三)——Dropping Partitions
  6. 我在河南安阳拍摄的一个山村小孩儿
  7. Visual Studio的Web Performance Test提取规则详解(1)
  8. python canopen_Python canopener包_程序模块 - PyPI - Python中文网
  9. centos6安装python_如何在CentOS6上安装Python2.7和Python3.3
  10. 计算机视觉基础:图像处理Task01-图像插值算法
  11. File类和各种io类会不会自动创建文件
  12. Visual Studio 远程调试设置
  13. 深度剖析 C++ 对象池自动回收技术实现
  14. Servlet原理:
  15. 两款个人知识库管理软件下载
  16. iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码
  17. 操作系统 文件索引结构
  18. 使用mysqladmin检测MySQL运行状态的教程
  19. CAcls命令在提权中的使用
  20. 随想,产品思维和开发思维

热门文章

  1. Linux运维:Shell脚本实现ssh免密登录远程服务器
  2. 2016猴年春联集锦
  3. iOS静态库中打包图片资源
  4. (4.3C)神奇的口袋
  5. Python——LeetCode刷题——【387. 字符串中的第一个唯一字符】
  6. 修改内核参数 dad_transmits
  7. Visual Studio Code使用教程
  8. 计算机网络节点分为三类,计算机网络技术1—2——3章
  9. 天池AI学习全面升级,所有学习资源都给你你汇总好啦!
  10. tshark命令小结