好久没做题了,建图搞了好久…… 然后,判是否有多解的时候会把原来的答案覆盖掉…… 这里没注意,弄了一下午……

代码:

  

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

  1. hdu 4069 垃圾数独

    首先dfs给每个格子分一个大的区块 其次套板子就a 我一开始直接在选取行的时候填数独,发现超时 我这一行也就4个元素,找到 x <= 81 的列计算元素位置,81 < x <= 16 ...

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

  3. hdu 4069 福州赛区网络赛I DLC ***

    再遇到一个DLC就刷个专题 #include <stdio.h> #include <string.h> #include <iostream> #include ...

  4. (中等) 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 ...

  5. HDU 1426(数独 DFS)

    题意是完成数独. 记录全图,将待填位置处填 0,记录下所有的待填位置,初始化结束.在每个待填位置处尝试填入 1 - 9,若经过判断后该位置可以填入某数字,则继续向下填下一个位置, 回溯时把待填位置重新 ...

  6. HDU - 5547 数独(回溯法)

    题目链接:HDU-5547 http://acm.hdu.edu.cn/showproblem.php?pid=5547 正所谓:骗分过样例,暴力出奇迹. 解题思想(暴力出奇迹(DFS+回溯)): 1 ...

  7. [DLX+bfs] hdu 4069 Squiggly Sudoku

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

  8. hdu 3909 数独扩展

    思路:做法与9*9的一样.只不过是变量. #include<set> #include<map> #include<cmath> #include<queue ...

  9. Dancing Links [Kuangbin带你飞] 模版及题解

    学习资料: http://www.cnblogs.com/grenet/p/3145800.html http://blog.csdn.net/mu399/article/details/762786 ...

随机推荐

  1. POST和GET详解

    GET和POST Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上 ...

  2. 命令行导入导出Mysql数据库

    MySQL命令行导出数据库:1,进入MySQL目录下的bin文件夹:cd MySQL中到bin文件夹的目录,如我输入的命令行:cd C:\Program Files\MySQL\MySQL Serve ...

  3. db2 -- 存储过程01

    接下来项目在技能可能偏向数据库方面,补习下. 学习写第一个db2在存储过程,记录下. ---- stored procedures code CREATE OR REPLACE PROCEDURE & ...

  4. python 多列表对应的位置的值形成一个新的列表

    list1 = [1, 2, 3, 4, 5] list2 = ['a','b', 'c', 'd', 'e'] list3 = [1, 2, 3, 4, 5] multi_list = map(li ...

  5. python 网络编程 粘包问题

    1.粘包现象 TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾.   粘包出现原因 使用了优化方法(Nagle算法),将多次间隔较小.数据 ...

  6. JAVA多线程知识总结(二)

    本文是承接上一篇文章:JAVA多线程知识总结(一) 四.Java多线程的阻塞状态与线程控制  上文已经提到线程阻塞的集中具体类型.下面主要看引起JAVA线程阻塞的方法 1,join()-----让一个 ...

  7. 2015 Multi-University Training Contest 8 hdu 5389 Zero Escape

    Zero Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  8. 2015 Multi-University Training Contest 5 hdu 5352 MZL's City

    MZL's City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  9. ASP.NET-GUID扩展类使用

    在NUGET上有一个GUID的类,安装试用一下它的方法 将string转为guid对象 Guid ad = new Guid("{99009327-15D2-4A69-B015-BEAC11 ...

  10. ASP.NET-Router配置中MapRoute的参数

    App_Start文件夹中的RouteConfig MapRoute(string name,string url); MapRoute(string name,string url,object d ...