题目大意:

这是一个最简单的数独填充题目,题目保证只能产生一种数独,所以这里的初始9宫格较为稠密,可以直接dfs也没有问题

但最近练习dancing links,这类数据结构解决数独无疑效率会高很多

dancing links的数独限制条件是:

1.每行有9个元素,共9行 对应dlx81列

2.每列有9个元素,共9行 对应dlx81列

3.每个九宫格有9个元素,共9行 对应dlx81列

4.81个格子,每个格子最多有一个数

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <climits>
#include <cmath> using namespace std;
#define N 1000
#define MAXNODE 1000000
const int INF = INT_MAX;
const double eps = 1e-; int a[][];
char str[]; int belong[][] = {
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
{,,,,,,,,},
};
struct DLX{
int n ,m , size;
int col[MAXNODE] , row[MAXNODE];
int U[MAXNODE] , D[MAXNODE] , L[MAXNODE] , R[MAXNODE];
int cnt_col[N] , first[N];
int ans[]; void init(int _n , int _m)
{
n = _n , m = _m;
size= m ;
for(int i= ; i<=m ; i++){
L[i] = i- , R[i] = i+;
U[i] = D[i] = i;
}
L[] = m , R[m] = ;
for(int i= ; i<=m ; i++) cnt_col[i] = ;
for(int i= ; i<=n ; i++) first[i] = -;
} void link(int r , int c)
{
++size;
U[D[c]] = size , D[size] = D[c];
U[size] = c , D[c] = size; if(first[r]<) L[size]=R[size]=first[r] = size;
else{
L[R[first[r]]] = size , R[size] = R[first[r]];
L[size] = first[r] , R[first[r]] = size;
}
row[size] = r , col[size] = c , cnt_col[c]++;
} void Remove(int c)
{
L[R[c]] = L[c] , R[L[c]] = R[c];
for(int i=D[c] ; i!=c ; i=D[i]){
for(int j=R[i] ; j!=i ; j=R[j]){
U[D[j]] = U[j] , D[U[j]] = D[j];
cnt_col[col[j]]--;
}
}
} void Resume(int c)
{
for(int i=U[c] ; i!=c ; i=U[i]){
for(int j=L[i] ; j!=i ; j=L[j]){
U[D[j]] = D[U[j]] = j;
cnt_col[col[j]]++;
}
}
L[R[c]] = R[L[c]] = c;
} bool Dance(int d)
{
if(!R[]){
for(int i= ; i<d ; i++){
int r = (ans[i]-)/;
int c = ((ans[i]-)%)/;
a[r][c] = ((ans[i]-)%)+;
}
return true;
}
int st=R[];
for(int i=R[] ; i!= ; i=R[i])
if(cnt_col[i]<cnt_col[st])
st = i;
Remove(st);
for(int i=D[st] ; i!=st ; i=D[i]){
ans[d] = row[i];
for(int j=R[i] ; j!=i ; j=R[j]) Remove(col[j]);
if(Dance(d+)) return true;
for(int j=L[i] ; j!=i ; j=L[j]) Resume(col[j]);
}
Resume(st);
return false;
} }dlx; void printM()
{
for(int i= ; i< ; i++)
for(int j= ; j< ; j++){
if(j<) printf("%d " , a[i][j]);
else printf("%d\n" , a[i][j]);
}
} int main()
{
// freopen("a.in" , "r" , stdin);
int index=;
bool flag = false;
while(~scanf("%s" , str))
{
if(flag) puts("");
flag = true;
if(str[] == '?') a[index/][index%] = ;
else a[index/][index%] = str[]-'';
index++;
while(index<){
scanf("%s" , str);
if(str[] == '?') a[index/][index%] = ;
else a[index/][index%] = str[]-'';
index++;
}
// printM();
dlx.init( , );
for(int i= ; i< ; i++)
for(int j= ; j< ; j++)
{
if(a[i][j]){
dlx.link((i*+j)*+a[i][j] , i*+a[i][j]);
dlx.link((i*+j)*+a[i][j] , +j*+a[i][j]);
dlx.link((i*+j)*+a[i][j] , +(belong[i][j]-)*+a[i][j]);
dlx.link((i*+j)*+a[i][j] , +i*+j+);
}
else{
for(int k= ; k<= ; k++){
dlx.link((i*+j)*+k , i*+k);
dlx.link((i*+j)*+k , +j*+k);
dlx.link((i*+j)*+k , +(belong[i][j]-)*+k);
dlx.link((i*+j)*+k , +i*+j+);
}
}
}
dlx.Dance(); printM();
index=;
} return ;
}

HDU 1426 dancing links解决数独问题的更多相关文章

  1. hihoCoder #1321 : 搜索五•数独 (Dancing Links ,精确覆盖)

    hiho一下第102周的题目. 原题地址:http://hihocoder.com/problemset/problem/1321 题意:输入一个9*9数独矩阵,0表示没填的空位,输出这个数独的答案. ...

  2. 浅入 dancing links x(舞蹈链算法)

    abastract:利用dancing links 解决精确覆盖问题,例如数独,n皇后问题:以及重复覆盖问题. 要学习dacning links 算法,首先要先了解该算法适用的问题,精确覆盖问题和重复 ...

  3. Dancing Links X 学习笔记

    \(\\\) Definitions 双向链表:记录前后两个指针的链表,每个顺序关系都有双向的指针维护. \(Dancing\ Links\):双向十字循环链表,建立在二维关系上,每个元素记录上下左右 ...

  4. [HDU1017]Exact cover[DLX][Dancing Links详解][注释例程学习法]

    Dancing Links解决Exact Cover问题. 用到了循环双向十字链表. dfs. 论文一知半解地看了一遍,搜出一篇AC的源码,用注释的方法帮助理解. HIT ACM 感谢源码po主.链接 ...

  5. 算法实践——舞蹈链(Dancing Links)算法求解数独

    在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dancing Links)算法求解精确覆盖问题. 本文介绍该算法的实际运用,利用舞蹈链(Dancin ...

  6. 转载 - 算法实践——舞蹈链(Dancing Links)算法求解数独

    出处:http://www.cnblogs.com/grenet/p/3163550.html 在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dan ...

  7. hdu 1426 Sudoku Killer ( Dancing Link 精确覆盖 )

    利用 Dancing Link 来解数独 详细的能够看    lrj 的训练指南 和 < Dancing Links 在搜索中的应用 >这篇论文 Dancing Link 来求解数独 , ...

  8. HDU 3335 Divisibility dancing links 重复覆盖

    分析: dlx重复覆盖的巧用,重复覆盖的原理恰好符合本题的筛选方式,即选择一个数后,该数的倍数或约数可以保证在之后的搜索中不会被选择 于是修改一下启发函数,求解最大的重复覆盖即可.   其实不一定不被 ...

  9. HDU 2295 Radar dancing links 重复覆盖

    就是dancing links 求最小支配集,重复覆盖 精确覆盖时:每次缓存数据的时候,既删除行又删除列(这里的删除列,只是删除表头) 重复覆盖的时候:只删除列,因为可以重复覆盖 然后重复覆盖有一个估 ...

随机推荐

  1. 虚方法virtual详解

    虚方法virtual详解   从C#的程序编译的角度来看,它和其它一般的函数有什么区别呢?一般函数在编译时就静态地编译到了执行文件中,其相对地址在程序运行期间是不发生变化的,也就是写死了的!而虚函数在 ...

  2. java 自定义注解,并使用示例

    场景: 对需要校验  手机验证码和短信验证码的controller方法添加 自定义的注解 @CheckType 1. 定义注解 /** * 需要短信.验证码验证方法上的注解 * date: 2018年 ...

  3. return false 的其中一种用法

    return false 的具体是做什么的在这里就不多说了,因为我觉得我形容不明白.....避免大家弄混乱,就不给大家添麻烦了~~ 直接上例子: 1.先看看下面一段代码,指出其中的错误所在: //点击 ...

  4. UVM基础之------uvm_transaction

    uvm_transaction继承自uvm_object,添加了timing和recording接口,该类是uvm_sequence_item的基类.下边将做剖析 1. 这个类提供了时间戳属性(tim ...

  5. SQL 导出csv

    https://jingyan.baidu.com/album/4b07be3c466b5d48b280f37f.html?picindex=9

  6. 基于 python 的接口测试框架

    项目背景 公司内部的软件采用B/S架构,管理实验室数据,实现数据的存储和分析统计.大部分是数据的增删改查,由于还在开发阶段,所以UI界面的变化非常快,之前尝试过用python+selenium进行UI ...

  7. SAP CRM调查问卷的评分和图表显示功能介绍

    SAP CRM里我们使用事务码CRM_SURVEY_SUITE创建一个调查问卷(Survey): 其中调查问卷的问题和答案均可分配权值(Rate),最后该问卷总的分数等于每个问题的权值乘以客户选择答案 ...

  8. js生成随机的uuid

    function generateUUID() { var d = new Date().getTime(); if(window.performance && typeof wind ...

  9. 1+1/2+1/3+...+1/n为素数的证明

    我们考虑不大于 n的最大的2 的幂 2^k. 令 有 其中 a/b是剩下的所有的项的和,由于乘以了最大的 2的幂,所以剩下的所有项的分母都是奇数,故而 b是奇数.如果 m是整数,那么就会导致等式右边的 ...

  10. easyui权限管理

    在easyui上实现权限的管理 所谓权限:指的是系统中的资源,资源包括菜单资源(学习情况报表,账号审核...)以及按钮资源所谓角色:指的是系统中的权限集合(每一个角色对应着哪些权限集合) 1.一星权限 ...