题目链接: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):

 #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)的更多相关文章

  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. 面向对象之virtual

    1.父类声明一个虚方法,子类可以对其进行重写(也可以不重写) 2.虚方法必须有方法体,抽象方法必须没有方法体 3.虚方法可以出现在抽象类中,抽象方法必须出现在抽象类中

  2. Google 开源项目风格指南

    Python风格规范 分号 Tip 不要在行尾加分号, 也不要用分号将两条命令放在同一行. 行长度 Tip 每行不超过80个字符 例外: 长的导入模块语句 注释里的URL 不要使用反斜杠连接行. Py ...

  3. Redis-秒杀场景应用

    Redis Util实现 package test.jedis; import java.util.List; import java.util.Set; import redis.clients.j ...

  4. 图形显示之RGB

    记得初中学数学几何时,有这样一句话:点运动成线,线运动成面,面运动成体. 其它方面也有相似的原理. 例如常见的gif动态图,就是由一帧一帧的图片快速切换得到的.那么,图片又是怎么显示的呢? 一副图片是 ...

  5. C#远程共享文件路径访问

    public class Win32ServiceManager    {        private string strPath;        private ManagementClass ...

  6. linux pipe

    1. 函数说明 pipe(建立管道): 1) 头文件 #include<unistd.h> 2) 定义函数: int pipe(int filedes[2]); 3) 函数说明: pipe ...

  7. How To Set Up Apache with a Free Signed SSL Certificate on a VPS

    Prerequisites Before we get started, here are the web tools you need for this tutorial: Google Chrom ...

  8. Java学习-015-CSV 文件写入实例源代码

    在日常的自动化测试脚本编写的过程中,有时要将获取的测试结果或者测试数据存放在数据文件中,以用作后续的参数化测试.常用的文件文件类型无非 txt.csv.xls.properties.xml 这五种文件 ...

  9. Win10如何开启IIS服务以及如何打开IIS管理器

    一.开启IIS服务 1.右键点击开始菜单或者使用“win+x”组合键,如然后选择“控制面板”,下如: 2.再控制面板中选择“程序”-->“启动或关闭windows功能”,在弹出的对话框中勾选如下 ...

  10. MVC4怎么设置@Html.TextBoxFor这样的输入框的css样式

    在传统webForm中,输入框的这样的: <input id="userName" name="userName" type="text&quo ...