UVALive 2659 数独 DLX模板
建图:
从1到16枚举所有的行、列上放的数。
代码:
#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 MAXNODE = ;
const int 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;
} bool dfs(int d) { //d为递归深度
if (R[] == ) { //找到解
ansd = d; //记录解的长度
return true;
} //找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列
ans[d] = row[i];
for (int j = R[i]; j != i; j = R[j]) remove(col[j]); //删除节结点i所在行覆盖第c列
if (dfs(d+)) return true;
for (int j = L[i]; j != i; j = L[j]) restore(col[j]); // 恢复
}
restore(c); //恢复
return false;
} bool solve(vector<int> &v) {
v.clear();
if(!dfs()) return false;
for (int i = ; i < ansd; i++) v.push_back(ans[i]);
return true;
}
}; 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;
} char puzzle[][]; bool read() {
for (int i = ; i < ; i++)
if (scanf("%s", puzzle[i])!=) return false;
return true;
} DLX solver; int main() {
#ifdef Phantom01
freopen("LA2659.txt", "r", stdin);
#endif //Phantom01 int T= ; while (read()) {
if (T!=) puts(""); T++;
solver.init();
for (int r = ; r < ; r++)
for (int c = ; c < ; c++)
for (int v = ; v < ; v++)
if (puzzle[r][c]=='-'|| puzzle[r][c]=='A'+v) {
vector<int> columns;
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, (r/)*+c/, v));
solver.addRow(encode(r, c, v), columns);
}
vector<int> ans;
if (!solver.solve(ans)) while () ; for (int i = ; i < ans.size(); i++) {
int r, c, v;
decode(ans[i], r, c, v);
puzzle[r][c] = 'A'+v;
}
for (int i = ; i < ; i++) {
printf("%s\n", puzzle[i]);
}
} return ;
}
UVALive 2659 数独 DLX模板的更多相关文章
- poj 3740 Easy Finding 二进制压缩枚举dfs 与 DLX模板详细解析
题目链接:http://poj.org/problem?id=3740 题意: 是否从0,1矩阵中选出若干行,使得新的矩阵每一列有且仅有一个1? 原矩阵N*M $ 1<= N <= 16 ...
- hdu 5046 二分+DLX模板
http://acm.hdu.edu.cn/showproblem.php?pid=5046 n城市建k机场使得,是每个城市最近机场的距离的最大值最小化 二分+DLX 模板题 #include < ...
- [ACM] POJ 3740 Easy Finding (DLX模板题)
Easy Finding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16178 Accepted: 4343 Des ...
- DLX模板
对于数独问题 ; //3*3数独 ; // 一格能填9个数 9*9格 +; // 9*9*4=(9+9+9)*9+9*9 (9+9+9)是9行 9列 9格 *9是9个数 9*9是81个格子 +MaxM ...
- [ACM] HUST 1017 Exact cover (Dancing Links,DLX模板题)
DESCRIPTION There is an N*M matrix with only 0s and 1s, (1 <= N,M <= 1000). An exact cover is ...
- Poj3074-Sudoku(数独DLX)
题意: 给出一个9*9的矩阵,有一些格子已经填了数,有一些是.代表未填.求任意一组解使得每行包含1~9,每列包含1~9,每个小矩形(3*3)包含1~9. 解析: 精确覆盖DLX的经典题目,每一行代表要 ...
- 51 nod 1211 数独 DLX
原题链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1211 调了挺久的,自己的一份舞蹈链模板…… 算是在网上见到的模 ...
- 舞蹈链 DLX
欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 舞蹈链是一个非常玄学的东西…… 问题模型 精确覆盖问题:在一个01矩阵中,是否可以选出一些行的集合,使得在这些行的集 ...
- 【UVA1309】Sudoku(DLX)
点此看题面 大致题意: 让你填完整一个\(16*16\)的数独. 解题思路 我们知道,数独问题显然可以用\(DLX\)解决. 考虑对于一个数独,它要满足的要求为:每个位置都必须有数,每一行都必须有全部 ...
随机推荐
- 使用终端改变MAC默认截图存放地址
使用终端改变MAC默认截图存放地址的过程主要分为两步: 第一步:输入如下命令,回车 defaults write com.apple.screencapture location 要存放到的位置的绝对 ...
- 05:Cave Cows 1 洞穴里的牛之一
总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 262144kB 描述 很少人知道其实奶牛非常喜欢到洞穴里面去探险. 洞窟里有N(1≤N≤100)个洞室,由 ...
- 有关马氏距离和hinge loss的学习记录
关于度量学习,之前没有看太多相关的文献.不过南京的周老师的一篇NIPS,确实把这个问题剖析得比较清楚. Mahalanobis距离一般表示为d=(x-y)TM(x-y),其中x和y是空间中两个样本点, ...
- 编译Speex生成so库文件(android-speex)
项目中需要用音频格式转换,之前使用VoAacEncoder,部分手机总是莫名崩溃,所以决定不再使用VoAacEncoder,换做Speex来完成格式转换,但是没有找到Speex的库文件,网上介绍的都是 ...
- ASP.NET MVC 使用FluentScheduler做定时任务
源代码地址: https://github.com/fluentscheduler/FluentScheduler 使用NuGet安装FluentScheduler 这是我实际项目中用到的代码,也可看 ...
- Python中编写精美图形界面(PyQt5)
纯代码,布局的讲解 见: https://cloud.tencent.com/developer/article/1345469 Qt designer设计文件 .ui转 .py文件,进阶使用 注:不 ...
- .Net基础杂记
1.面向对象程序思想 面向对象是程序开发的一种机制,特征为封装.继承.多态.以面向对象方式编写程序时,将复杂的项目抽象为多个对象互相协作的模型,然后编写模型结构,声明或实现类型的成员,即描述对象的特征 ...
- 【转载·】Linux yum 安装 gcc 、gcc-c++
2017年09月29日 22:45:54 上善若水 阅读数:6653更多 个人分类: Linux学习 所属专栏: Linux学习杂技 版权声明:本文为博主原创文章,未经博主允许不得转载. ht ...
- 做一个可复用的 echarts-vue 组件(延迟动画加载)
在 vue 项目使用 echarts 的场景中,以下三点不容忽视:1. 可视化的数据往往是异步加载的:2. 若一个页面存在大量的图表( 尤其当存在关系图和地图时 ),往往会导致该页面的渲染速度很慢并可 ...
- win系统安装node出现这个2503和2502解决办法
一: 今天在公司的新电脑要安装appium,所以要搭建appium的环境,所以在安装到node的时候,出现了内部错误2503和2502,安装中断. 这种错误可能是权限不足导致,一般“.exe”程序可以 ...