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):
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
typedef long long LL; const int MAXN = ;
const int MAXC = * * + ;
const int MAXR = * * + ;
const int MAXP = MAXR * + MAXC; struct DLX {
int sz;
int sum[MAXC];
int row[MAXP], col[MAXP];
int left[MAXP], right[MAXP], up[MAXP], down[MAXP];
int ansd, ans[MAXR], anscnt; void init(int n) {
for(int i = ; i <= n; ++i) {
up[i] = down[i] = i;
left[i] = i - ; right[i] = i + ;
}
left[] = n; right[n] = ;
sz = n + ;
memset(sum, , sizeof(sum));
} void add_row(int r, vector<int> &func) {
int first = sz;
for(size_t i = ; i < func.size(); ++i) {
int c = func[i];
left[sz] = sz - ; right[sz] = sz + ; up[sz] = up[c]; down[sz] = c;
down[up[c]] = sz; up[c] = sz;
row[sz] = r; col[sz] = c;
++sum[c], ++sz;
}
left[first] = sz - ; right[sz - ] = first;
} void remove(int c) {
left[right[c]] = left[c];
right[left[c]] = right[c];
for(int i = down[c]; i != c; i = down[i]) {
for(int j = right[i]; j != i; j = right[j])
up[down[j]] = up[j], down[up[j]] = down[j], --sum[col[j]];
}
} void restore(int c) {
for(int i = up[c]; i != c; i = up[i]) {
for(int j = left[i]; j != i; j = left[j])
up[down[j]] = j, down[up[j]] = j, ++sum[col[j]];
}
left[right[c]] = c;
right[left[c]] = c;
} bool dfs(int d) {
if(!right[]) {
ansd = d;
return ++anscnt == ;
}
int c = right[];
for(int i = right[]; i != ; i = right[i]) if(sum[i] < sum[c]) c = i;
remove(c);
for(int i = down[c]; i != c; i = down[i]) {
if(!anscnt) ans[d] = row[i];
for(int j = right[i]; j != i; j = right[j]) remove(col[j]);
if(dfs(d + )) return true;
for(int j = left[i]; j != i; j = left[j]) restore(col[j]);
}
restore(c);
return false;
} int solve(vector<int> &v) {
v.clear();
anscnt = ;
dfs();
if(anscnt == ) for(int i = ; i < ansd; ++i) v.push_back(ans[i]);
return anscnt;
}
} solver; const int SLOT = ;
const int ROW = ;
const int COL = ;
const int SUB = ; int fr[] = {-, , , };
int fc[] = {, , , -};
int fp[] = {, , , }; int mat[MAXN][MAXN];
int val[MAXN][MAXN], cnt;
int T, n = ; bool in_n(int x) {
return <= x && x < n;
} void dfs(int r, int c, int p) {
val[r][c] = p;
for(int i = ; i < ; ++i) {
int nr = r + fr[i], nc = c + fc[i];
if(in_n(nr) && in_n(nc) && ((fp[i] & mat[r][c]) == ) && !val[nr][nc])
dfs(nr, nc, p);
}
} void print(int mat[MAXN][MAXN]) {
for(int i = ; i < n; ++i) {
for(int j = ; j < n; ++j) printf("%d", mat[i][j]);
puts("");
}
} int encode(int a, int b, int c) {
return a * + b * + c + ;
} void decode(int code, int &a, int &b, int &c) {
--code;
c = code % ; code /= ;
b = code % ; code /= ;
a = code;
} int main() {
scanf("%d", &T);
for(int kase = ; kase <= T; ++kase) {
for(int i = ; i < n; ++i)
for(int j = ; j < n; ++j) scanf("%d", &mat[i][j]);
memset(val, , sizeof(val));
cnt = ;
for(int i = ; i < n; ++i)
for(int j = ; j < n; ++j) if(!val[i][j]) dfs(i, j, ++cnt);
printf("Case %d:\n", kase);
//print(val);
solver.init( * * );
for(int r = ; r < n; ++r)
for(int c = ; c < n; ++c)
for(int i = ; i < ; ++i) mat[r][c] &= ~fp[i];
//print(mat);
for(int r = ; r < n; ++r) for(int c = ; c < n; ++c) for(int v = ; v < n; ++v) {
if(!mat[r][c] || mat[r][c] == + v) {
vector<int> func;
func.push_back(encode(SLOT, r, c));
func.push_back(encode(ROW, r, v));
func.push_back(encode(COL, c, v));
func.push_back(encode(SUB, val[r][c] - , v));
solver.add_row(encode(r, c, v), func);
}
}
vector<int> ans;
int res = solver.solve(ans);
if(res == ) puts("No solution");
if(res == ) {
int r, c, v;
for(size_t i = ; i < ans.size(); ++i) {
decode(ans[i], r, c, v);
mat[r][c] = + v;
}
print(mat);
}
if(res == ) puts("Multiple Solutions");
}
}
HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)的更多相关文章
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- (并查集)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 ...
- (二叉树)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) ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- C# Unicode编码与解码方法
public static class ExtentMethod { public static string ToUnicodeString(this string str) { StringBui ...
- jfinal
http://blog.csdn.net/zb0567/article/details/21083021
- java并发编程-线程池的使用
参考文章:http://www.cnblogs.com/dolphin0520/p/3932921.html 深入剖析线程池实现原理 将从下面几个方面讲解: 1.线程池状态 2.任务的执行 3.线程池 ...
- Strom简介,以及安装,和官方案例测试
一:简介 1.strom的两种形式 2.strom的特性 3.使用场景 4.集群架构 5.集群架构进程 6.组件 Nimbus 7.从节点Supervisor 8.组件worker 9.组件Execu ...
- scala 学习笔记
1.简洁 1.1.java的写法 class MyClass { private int index; private String name; public MyClass(int index, S ...
- php--字符串函数分类总结
PHP语言中的字符串函数也是一个比较易懂的知识.今天我们就为大家总结了将近12种PHP字符串函数,希望对又需要的朋友有所帮助,增加读者朋友的PHP知识库. 1.查找字符位置函数 strpos($s ...
- mongoose find查询意错点
//使用mongoose查询文档所有结果时容易出现的问题 ArticleContents.getAll = function(name, callback){ var query = {}; if(n ...
- Spark Programming--Actions
first def first(): T first返回RDD中的第一个元素,不排序. 例子: count def count(): Long count返回RDD中的元素数量 例子: reduce ...
- JS之call/apply/bind
测试代码: var a = 1; var obj = { a = 2; } function test(a){ alert(a); alert(this.a); } 1.test(3); 结果:3,1 ...
- windows下memcache安装及配置
1.安装memcached服务,链接为http://i.cnblogs.com/Files.aspx, 下载解压后放在一个文件夹下,在开始搜索中输入cmd, 进入cmd黑框,cd 路径,进入memca ...