HDU 4069 数独
好久没做题了,建图搞了好久…… 然后,判是否有多解的时候会把原来的答案覆盖掉…… 这里没注意,弄了一下午……
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <cctype>
#include <time.h> using namespace std; const int INF = <<;
const int MAXN = **+;
const int MAXR = **+;
const int MAXNODE = MAXN*MAXR+; struct DLX {
// 行编号从1开始,列编号为1~n,结点0是表头结点;结点1~n是各列顶部的虚拟结点
int n, sz; // 列数,结点总数
int S[MAXN]; //各列结点数 int row[MAXNODE], col[MAXNODE]; //各结点行列编号
int L[MAXNODE], R[MAXNODE], U[MAXNODE], D[MAXNODE]; //十字链表 int ansd, ans[MAXR]; // 解 void init(int n) { //n是列数
this->n = n; //虚拟结点
for (int i = ; i <= n; i++) {
U[i] = i; D[i] = i; L[i] = i-; R[i] = i+;
}
R[n] = ; L[] = n;
sz = n+;
memset(S, , sizeof(S));
} void addRow(int r, vector<int> columns) {
//这一行的第一个结点
//行没有设头结点,每一行连成一个环形
int first = sz;
for (int i = ; i < columns.size(); i++) {
int c = columns[i];
L[sz] = sz-; R[sz] = sz+; D[sz] = c; U[sz] = U[c];
D[U[c]] = sz; U[c] = sz;
row[sz] = r; col[sz] = c;
S[c]++; sz++;
}
R[sz-] = first; L[first] = sz-;
} //顺着链表A,遍历s外的其他元素
#define FOR(i, A, s) for (int i = A[s]; i != s; i = A[i]) void remove(int c) { //删除c列
L[R[c]] = L[c]; R[L[c]] = R[c];
for (int i = D[c]; i != c; i = D[i]) // 对于每一个c列不为0的所有行
for (int j = R[i]; j != i; j = R[j]) { //删除这一整行
U[D[j]] = U[j]; D[U[j]] = D[j]; S[col[j]]--;
}
} void restore(int c) { //回连c列
for (int i = U[c]; i != c; i = U[i])
for (int j = L[i]; j != i; j = L[j]) {
U[D[j]] = j; D[U[j]] = j; S[col[j]]++;
}
L[R[c]] = c; R[L[c]] = c;
} int flag; void dfs(int d) { //d为递归深度
if (R[] == ) { //找到解
ansd = d; //记录解的长度
flag++;
return ;
} //找S最小的C列
int c = R[]; //第一个未删除的列
for (int i = R[]; i != ; i = R[i]) if (S[i]<S[c]) c = i;
remove(c); //删除第c列
for (int i = D[c]; i != c; i = D[i]) { //用结点i所在的行覆盖第c列
if (!flag) ans[d] = row[i];
for (int j = R[i]; j != i; j = R[j]) remove(col[j]); //删除节结点i所在行覆盖第c列
dfs(d+);
if (flag>) return ;
for (int j = L[i]; j != i; j = L[j]) restore(col[j]); // 恢复
}
restore(c); //恢复
} int solve(vector<int> &v) {
v.clear();
flag = ;
dfs();
for (int i = ; i < ansd; i++) v.push_back(ans[i]);
return flag;
}
}; const int dir[][] = { {-, }, {, }, {, }, {, -} }; const int SLOT = ;
const int ROW = ;
const int COL = ;
const int SUB = ; inline int encode(int a, int b, int c) { return a*+b*+c+; }
inline void decode(int code, int &a, int &b, int &c) {
code--;
c = code%; code /= ;
b = code%; code /= ;
a = code;
} DLX solver;
int Matrix[][];
int belong[][];
int cnt; vector<int> columns; void test() { int *p = ; (*p) = ; } void dfs(int r, int c, int num) {
belong[r][c] = cnt;
int t = Matrix[r][c]>>;
int nr, nc;
for (int i = ; i < ; i++) if (!(t&(<<i))) {
nr = r+dir[i][]; nc = c+dir[i][];
if (!(<=nr&&nr<)||!(<=nc&&nc<)||belong[nr][nc]!=-) continue;
dfs(nr, nc, num+);
}
} void solve() {
solver.init(**);
for (int r = ; r < ; r++) {
for (int c = ; c < ; c++) {
Matrix[r][c] %= ;
for (int v = ; v <= ; v++) {
if (Matrix[r][c]!= && Matrix[r][c]!=v) continue;
columns.clear();
columns.push_back(encode(SLOT, r, c));
columns.push_back(encode(ROW, r, v-));
columns.push_back(encode(COL, c, v-));
columns.push_back(encode(SUB, belong[r][c], v-));
solver.addRow(encode(r, c, v-), columns);
}
}
} int ans = solver.solve(columns);
if (ans == ) { puts("Multiple Solutions"); return; }
if (ans == ) { puts("No solution"); return; }
for (int i = ; i < columns.size(); i++) {
int r, c, v;
decode(columns[i], r, c, v);
Matrix[r][c] = v+;
}
for (int r = ; r < ; r++) {
for (int c = ; c < ; c++) {
printf("%d", Matrix[r][c]);
}
puts("");
}
} int main() {
#ifdef Phantom01
freopen("HDU4069.txt", "r", stdin);
// freopen("HDU4069.out", "w", stdout);
#endif //Phantom01 int T;
scanf("%d", &T);
for (int C = ; C <= T; C++) {
printf("Case %d:\n", C);
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
scanf("%d", &Matrix[i][j]); for (int r = ; r < ; r++)
for (int c = ; c < ; c++)
belong[r][c] = -; cnt = ;
for (int r = ; r < ; r++) {
for (int c = ; c < ; c++) if (belong[r][c]==-){
dfs(r, c, );
cnt++;
}
}
solve();
} return ;
}
HDU 4069 数独的更多相关文章
- hdu 4069 垃圾数独
首先dfs给每个格子分一个大的区块 其次套板子就a 我一开始直接在选取行的时候填数独,发现超时 我这一行也就4个元素,找到 x <= 81 的列计算元素位置,81 < x <= 16 ...
- HDU 4069 Squiggly Sudoku(DLX)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4069 Problem Description Today we play a squiggly sud ...
- hdu 4069 福州赛区网络赛I DLC ***
再遇到一个DLC就刷个专题 #include <stdio.h> #include <string.h> #include <iostream> #include ...
- (中等) HDU 4069 Squiggly Sudoku , DLX+精确覆盖。
Description Today we play a squiggly sudoku, The objective is to fill a 9*9 grid with digits so that ...
- HDU 1426(数独 DFS)
题意是完成数独. 记录全图,将待填位置处填 0,记录下所有的待填位置,初始化结束.在每个待填位置处尝试填入 1 - 9,若经过判断后该位置可以填入某数字,则继续向下填下一个位置, 回溯时把待填位置重新 ...
- HDU - 5547 数独(回溯法)
题目链接:HDU-5547 http://acm.hdu.edu.cn/showproblem.php?pid=5547 正所谓:骗分过样例,暴力出奇迹. 解题思想(暴力出奇迹(DFS+回溯)): 1 ...
- [DLX+bfs] hdu 4069 Squiggly Sudoku
题意: 给你9*9的矩阵.对于每一个数字.能减16代表上面有墙,能减32代表以下有墙. .. 最后剩下的数字是0代表这个位置数要求,不是0代表这个数已知了. 然后通过墙会被数字分成9块. 然后做数独, ...
- hdu 3909 数独扩展
思路:做法与9*9的一样.只不过是变量. #include<set> #include<map> #include<cmath> #include<queue ...
- Dancing Links [Kuangbin带你飞] 模版及题解
学习资料: http://www.cnblogs.com/grenet/p/3145800.html http://blog.csdn.net/mu399/article/details/762786 ...
随机推荐
- redis 篇 - hash
hash 可以认为是 python 中的字典 field 不允许重复 string类型的field和value的映射表 每个hash可以存储 232 - 1 键值对(40多亿) 方法 hest key ...
- js获取路径参数对象
/** * 获取页面路径参数值 */ function getParams(key) { var result = {}; var paramStr = encodeURI(window.docume ...
- 实现js保留小数点后N位的代码
在JS中,一般实现保留小数点后N位的话,都是利用toFixed函数 <script language="javascript"> document.write(&quo ...
- BZOJ 3336 Black and White (插头DP)
题目大意: 给你一个n×m的网格,有一些格子已经被涂上了白色或者黑色,让你用黑色或白色填剩下的格子,且填好的网格必须保证: 1.对于任意2×2的子矩阵的4个格子,它们的颜色不能都相同 2.所有黑色的块 ...
- Flask-RESTful(转载)
Flask-RESTful 是一个 Flask 扩展,它添加了快速构建 REST APIs 的支持.它当然也是一个能够跟你现有的ORM/库协同工作的轻量级的扩展.Flask-RESTful 鼓励以最小 ...
- Tensorflow 读写 tfrecord 文件(Python3)
TensorFlow笔记博客:https://blog.csdn.net/xierhacker/article/category/6511974 写入tfrecord文件 import tensorf ...
- 支持Openflow 1.3的wireshark插件安装教程
目前为止,我们使用openflow wiki里提供的minient镜像里集成的wireshark只支持openflow1.0,我们通过wireshark上 菜单 help-->about wir ...
- 简单实现双向数据绑定mvvm。
- Nodejs RESTFul架构实践之api篇(转)
why token based auth? 此段摘自 http://zhuanlan.zhihu.com/FrontendMagazine/19920223 英文原文 http://code.tuts ...
- Collection、List、Set、Map之间的关系
初学java,单个的接触有点迷糊,所以总结下他们的关系 一.关系 Collection --List:以特定顺序存储 --ArrayList.LinkList.Vector --Set:不能包含重复的 ...