DLX算法及应用(一)DLX模板+解数独

DLX算法

原理:网上太多了,我就不写了。。

用途:解决精确覆盖问题

下面的代码是严格按照算法写的,其实对于这种没有数据域的链表,是可以用数组进行模拟的(见DLX算法及应用(二)Matlab解数独)。

代码中全部都用的是vector,更通用一些~


后半部分给出了一个解数独的实例,如何将数独转换为精确覆盖问题的文章也是网上一搜一大把。。。。我就不写了。。


2014-2-15 修改:还是写下如何转换吧

精确覆盖问题的矩阵表示:

给出这样一个矩阵,

1	0	0	1	0	0	1
1	0	0	1	0	0	0
0	0	0	1	1	0	1
0	0	1	0	1	1	0
0	1	1	0	0	1	1
0	1	0	0	0	0	1
找出该矩阵一组行的集合,使得该组集合中每列有且只有一个1

例如第2,4,6行


那么我们现在将数独问题转换成一个324列的精确覆盖问题:

数独有4个限制条件,将其分别转换为81列

每个格子都要填入数字
---1到81列,表示数独中9*9=81个格子是否填入了数字。如果是,则选取的01行在该01列上为1

每一行都要有1~9填入
---81+1到81*2列,每9列就代表数独中的一行,如果该行有某个数字,则其对应的列上为1

每一列都要有1~9填入
---81*2+1到81*3列,每9列就代表数独中的一列

每一宫都要有1~9填入
---81*3+1到81*4列,每9列就代表数独中的一宫


那让我们从第一个格子开始,到第81个格子,逐步构造01矩阵

对于已给出数字的格子,例如第 3 行第 5 列为7

那么就插入一行,其中,第23,106,205,259列为1,其他为0,分别代表:

23 =        (3-1)*9 + 5    第 3 行第 5 列填入了数字
106= 81   + (3-1)*9 + 7    第 3 行填入了7
205= 81*2 + (5-1)*9 + 7    第 5 列填入了7
259= 81*3 + (2-1)*9 + 7    第 2 宫填入了7

如果没有给出数字,那这个格子就有9种可能性,插入9行,其中如下列为1:

第一行:23,100,199,253
第二行:23,101,200,254
........
第九行:23,108,207,261
这样,构造的01矩阵,每行都有4个1。

在最多81*9行的01矩阵中,寻找一组精确覆盖(81行),就可以求解一个数独




代码如下

#include <time.h>
#include <iostream>
#include <limits.h>
#include <vector>
#include <fstream>
using namespace std;

struct Node{
    Node *up, *down, *left, *right, *colRoot, *rowRoot;//上下左右四个指针以及指向行列对象的指针
    int Num;//行对象特有,记录行数
    int Size;//列对象特有,记录该列元素数
    Node(int i = -1 ): Num(i),Size(0) {};//构造函数
};

class DLX{
public:
    DLX(vector<vector<int> > &matrix, int m, int n);
    ~DLX
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值