搜索:DLX算法
精确覆盖问题:在一个0-1矩阵中,选定部分行,使得每一列都有且只有一个1。求解一种选法
舞蹈链(Dance Link),也就是一个循环十字链表,可以快速的删掉和恢复某行某列
结合了舞蹈链的搜索就称作DLX算法
这里贴一个用DLX算法解决16×16数独的代码
9×9的直接暴力会更好
- // LA2659 Sudoku
- // Rujia Liu
- #include<cstdio>
- #include<cstring>
- #include<vector>
- using namespace std;
- const int maxr = ;
- const int maxn = ;
- const int maxnode = ;
- // 行编号从1开始,列编号为1~n,结点0是表头结点; 结点1~n是各列顶部的虚拟结点
- struct DLX {
- 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) {
- L[R[c]] = L[c];
- R[L[c]] = R[c];
- FOR(i,D,c)
- FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; }
- }
- void restore(int c) {
- FOR(i,U,c)
- FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; }
- L[R[c]] = c;
- R[L[c]] = c;
- }
- // d为递归深度
- bool dfs(int d) {
- if (R[] == ) { // 找到解
- ansd = d; // 记录解的长度
- return true;
- }
- // 找S最小的列c
- int c = R[]; // 第一个未删除的列
- FOR(i,R,) if(S[i] < S[c]) c = i;
- remove(c); // 删除第c列
- FOR(i,D,c) { // 用结点i所在行覆盖第c列
- ans[d] = row[i];
- FOR(j,R,i) remove(col[j]); // 删除结点i所在行能覆盖的所有其他列
- if(dfs(d+)) return true;
- FOR(j,L,i) restore(col[j]); // 恢复结点i所在行能覆盖的所有其他列
- }
- restore(c); // 恢复第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;
- }
- };
- ////////////// 题目相关
- #include<cassert>
- DLX solver;
- const int SLOT = ;
- const int ROW = ;
- const int COL = ;
- const int SUB = ;
- // 行/列的统一编解码函数。从1开始编号
- 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;
- }
- char puzzle[][];
- bool read() {
- for(int i = ; i < ; i++)
- if(scanf("%s", puzzle[i]) != ) return false;
- return true;
- }
- int main() {
- int kase = ;
- while(read()) {
- if(++kase != ) printf("\n");
- 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;
- assert(solver.solve(ans));
- 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 ;
- }
搜索:DLX算法的更多相关文章
- [蘑菇街] 搜索、算法团队招募牛人啦-年底了走过路过不要错过 - V2EX
[蘑菇街] 搜索.算法团队招募牛人啦-年底了走过路过不要错过 - V2EX [蘑菇街] 搜索.算法团队招募牛人啦-年底了走过路过不要错过
- 关于用舞蹈链DLX算法求解数独的解析
欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 描述 在做DLX算法题中,经常会做到数独类型的题目,那么,如何求解数独类型的题目?其实,学了数独的构建方法,那么DL ...
- 【DLX算法】hdu3498 whosyourdaddy
题意:给你一个01矩阵,让你选择尽可能少的行数,使得这些行的并集能够覆盖到所有列. DLX算法求解重复覆盖问题模板,使用估价函数进行剪枝. #include<cstdio> #includ ...
- 【DLX算法】poj2676 Sudoku
DLX算法求解精确覆盖问题模板.赛场上可以参见白书. #include<cstdio> #include<cstring> #include<vector> usi ...
- Python排序搜索基本算法之归并排序实例分析
Python排序搜索基本算法之归并排序实例分析 本文实例讲述了Python排序搜索基本算法之归并排序.分享给大家供大家参考,具体如下: 归并排序最令人兴奋的特点是:不论输入是什么样的,它对N个元素的序 ...
- 搜索相关性算法在 DiDi Food 中的搜索
导读:今天给大家分享的主题是搜索匹配问题在 DiDi Food 中的一些探索与应用.本文首先介绍了搜索相关性的一些背景,之后介绍了业界常见的三种匹配模型,以及在DiDi Food业务中的模型效果对比. ...
- 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)
图的遍历的定义: 从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次.(连通图与非连通图) 深度优先遍历(DFS): 1.访问指定的起始顶点: 2.若当前访问的顶点的邻接顶点有未被访问的,则 ...
- 广度优先搜索 BFS算法
广度优先搜索算法(Breadth-First-Search,BFS),又称作宽度优先搜索.BFS算法是从根节点开始,沿着树的宽度遍历树的节点.如果所有节点均被访问,则算法中止. 算法思想 1.首先将根 ...
- DLX算法一览
目录: 1 X思想的了解. 链表的递归与回溯. 具体操作. 优化. 一些应用与应用中的再次优化(例题). 练手题 X思想的了解. 首先了解DLX是什么? DLX是一种多元未饱和型指令集结构,DLX 代 ...
随机推荐
- 第9次Scrum会议(10/21)【欢迎来怼】
一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华小组照片 二.开会信息 时间:2017/10/21 17:20~17:45,总计25min.地点:东北师范 ...
- Haproxy + Rabbit 集群 简要介绍
# 两台主机都安装上rabbitMQ yum install -y rabbitmq-server # 两台主机都配置/etc/hosts文件 192.168.23.10 rabbitmq1 19 ...
- (一)MySQL基础篇
1.mysql简介 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库. 主流的数据库有:sqlserver,mysql,Oracle.SQLite.Access.MS SQL Se ...
- Halcon 笔记3 形态学
Halcon 三大数据类型: (1)图像 (2)区域 (3)XLD 查看时间工具 如果想让图像减少,则进行腐蚀(或者使用开运算),反之,则进行膨胀(或闭运算) 腐蚀后再进行膨胀,相当于进行开运算.因 ...
- SQL Server bit数据类型
bit值保存为1/0,1代表true,0代表false读取数据库数据时,可以直接用bool型读取该字段,会直接转换为true/false 数据库表结构 CREATE TABLE [dbo].[BitT ...
- H5跳转到百度地图并定位
找了半天的JS api,发现没有,后来发现这个叫 url api,让我好找. 官方文档: http://lbsyun.baidu.com/index.php?title=uri/api/web : 简 ...
- Importing/Indexing database (MySQL or SQL Server) in Solr using Data Import Handler--转载
原文地址:https://gist.github.com/maxivak/3e3ee1fca32f3949f052 Install Solr download and install Solr fro ...
- BZOJ 1222 产品加工(DP)
某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时由两台机器共同进行加工,所完成任 ...
- 【bzoj1430】小猴打架 Prufer序列
题目描述 给出 $n$ 个点,每次选择任意一条边,问这样 $n-1$ 次后得到一棵树的方案数是多少. 输入 一个整数N. 输出 一行,方案数mod 9999991. 样例输入 4 样例输出 96 题解 ...
- 【Mybatis】<foreach>标签在mybatis中的使用
mapper.xml如下: <select id="selectCkspcb" parameterType="java.util.Map" resultT ...