传送门:http://poj.org/problem?id=3074

DLX 数独的9*9的模板题。

具体建模详见下面这篇论文。其中9*9的数独怎么转化到精确覆盖问题,以及相关矩阵行列的定义都在下文中,描述的十分清晰

http://wenku.baidu.com/view/4ab7bd00a6c30c2259019eae.html

有关Dancing Links的英文论文详见下面链接

http://wenku.baidu.com/view/60eb28ded15abe23482f4d77.html

中文的:

http://wenku.baidu.com/view/d8f13dc45fbfc77da269b126.html

AC代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<algorithm> using namespace std;
// 列:(行+列+块)*9种可能+9*9个格子
// 行: 9*9*9 表示第i行第j列填k
const int MAXN=(9+9+9)*9+9*9+9*9*9*9*9*4+10;
#define INF 0xFFFFFF
int size;
int head,sz;
int U[MAXN],D[MAXN],L[MAXN],R[MAXN];
int H[MAXN],ROW[MAXN],C[MAXN],S[MAXN],O[MAXN]; 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];
--S[C[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])
{
++S[C[j]];
U[D[j]]=j;
D[U[j]]=j;
}
}
L[R[c]]=c;
R[L[c]]=c;
} bool dfs(int k)
{
if(R[head]==head)
{
sort(O,O+9*9);
int p=0;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
int num=O[p++];
//cout<<num<<endl;
num=num-(i*9+j)*9;
printf("%d",num);
}
}
printf("\n");
return true;
}
int s=INF,c;
for (int t=R[head];t!=head;t=R[t])
{
if (S[t]<s)
{
s=S[t];
c=t;
}
}
remove(c);
for(int i=D[c];i!=c;i=D[i])
{
O[k]=ROW[i];
for(int j=R[i];j!=i;j=R[j])
remove(C[j]);
if(dfs(k+1))
return true;
for(int j=L[i];j!=i;j=L[j])
resume(C[j]);
}
resume(c);
return false;
} void initDL(int n)
{
head=0;
for(int i=0;i<=n;i++)
{
U[i]=i;D[i]=i;
L[i]=i-1;R[i]=i+1;
S[i]=0;
}
R[n]=0;L[0]=n;S[0]=INF+1;
sz=n+1;
memset(H,0,sizeof(H));
} void insert(int i, int j)
{
if(H[i])
{
L[sz]=L[H[i]];
R[sz]=H[i];
L[R[sz]]=sz;
R[L[sz]]=sz;
}
else
{
L[sz]=sz;
R[sz]=sz;
H[i]=sz;
}
U[sz]=U[j];
D[sz]=j;
U[D[sz]]=sz;
D[U[sz]]=sz;
C[sz]=j;
ROW[sz]=i;
++S[j];
++sz;
} char str[200]; void build()
{
int p=0;
initDL(9*9*4);
for(int i=0;i<9;i++)
for(int j=1;j<=9;j++,p++)
{
int base=(i*9+j-1)*9;
if(str[p]=='.')
{
for(int k=1;k<=9;k++)
{
int r;
r=base+k;
//第i行有数字k
insert(r,i*9+k);
//第j列有数字k
insert(r,9*9+(j-1)*9+k);
//第k块有数字k
int block=(j-1)/3*3+i/3;
insert(r,9*9*2+block*9+k);
//第i行j列有一个数字(限制一个格子只填一个数)
insert(r,9*9*3+i*9+j);
}
}
else
{
int k=str[p]-'0';
int r=base+k;
//第i行有数字k
insert(r,i*9+k);
//第j列有数字k
insert(r,9*9+(j-1)*9+k);
//第k块有数字k
int block=(j-1)/3*3+i/3;
insert(r,9*9*2+block*9+k);
//第i行j列有一个数字(限制一个格子只填一个数)
insert(r,9*9*3+i*9+j);
}
}
} int main()
{
size=9; //9*9数独
while(~scanf("%s",str))
{
if(strcmp(str,"end")==0)
break;
build();
dfs(0);
}
return 0;
}

POJ 3074 Sudoku (Dancing Links)的更多相关文章

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

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

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

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

  3. 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...

  4. [转] 舞蹈链(Dancing Links)——求解精确覆盖问题

    转载自:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个 ...

  5. 算法帖——用舞蹈链算法(Dancing Links)求解俄罗斯方块覆盖问题

    问题的提出:如下图,用13块俄罗斯方块覆盖8*8的正方形.如何用计算机求解? 解决这类问题的方法不一而足,然而核心思想都是穷举法,不同的方法仅仅是对穷举法进行了优化 用13块不同形状的俄罗斯方块(每个 ...

  6. 【POJ3740】Easy Finding DLX(Dancing Links)精确覆盖问题

    题意:多组数据,每组数据给你几行数,要求选出当中几行.使得每一列都有且仅有一个1.询问是可不可行,或者说能不能找出来. 题解:1.暴搜.2.DLX(Dancing links). 本文写的是DLX. ...

  7. 转载 - 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    出处:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 ...

  8. 【POJ3074】Sudoku DLX(Dancing Links)

    数独就要DLX,不然不乐意. 数独的DLX构造:9*9个点每一个点有9种选择,这构成了DLX的729行,每行.列.阵有限制,均为9行(/列/阵),然后每行(/列/阵)都有九种数的情况.于是就有了3*9 ...

  9. ZOJ 3209 Treasure Map (Dancing Links)

    Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 KB Your boss once had got many copies of ...

随机推荐

  1. HDU 5407 CRB and Candies

    题意:给一个正整数k,求lcm((k, 0), (k, 1), ..., (k, k)) 解法:在oeis上查了这个序列,得知答案即为lcm(1, 2, ..., k + 1) / (k + 1),而 ...

  2. Binary Tree Level Order Traversal java实现

    Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...

  3. redis错误汇总

    1.redis因为内存不够而启动失败 Microsoft Open Tech group 在 GitHub上开发了一个REDIS Win64的版本,项目地址是:https://github.com/M ...

  4. HDU 3333-Turing Tree(BIT好题)

    题意: 给你n个数的序列a,q个询问,每个询问给l,r,求在下标i在[l,r]的区间内不含重复数的和 分析: 这类题目觉得很好,很练思维,觉得不太好做. 用BIT维护和,我们可以从前向后扫一遍序列,当 ...

  5. Jmeter教程

    博客园 http://www.cnblogs.com/yangxia-test/category/431240.html 1)分析能力没有LoadRunner详细 2)jmeter不支持IP欺骗,而L ...

  6. Selenium2Library系列 keywords 之 _SelectElementKeywords 之 _get_values_for_options(self, options)

    def _get_values_for_options(self, options): values = [] for option in options: values.append(option. ...

  7. 学习笔记 - 深究Bitmap压缩避免OOM的核心inSampleSize的最佳取值

    /** * 测试代码,通过在SDCard根目录放置几种不同大小的图片, 来自动测试压缩方式是否有效同时看是否会内存不够. * * @since * By:AsionTang * At:2014年3月2 ...

  8. csv文件与DataTable互相导入处理

    封装处理下,以后项目用到可以直接使用,比较简单. 1.首先看封装好的类 using System; using System.Data; using System.IO; using System.T ...

  9. 【windows核心编程】一个HOOK的例子

    一.应用场景 封装一个OCX控件,该控件的作用是来播放一个视频文件,需要在一个进程中放置四个控件实例. 由于控件是提供给别人用的,因此需要考虑很多东西. 二.考虑因素 1.控件的父窗口resize时需 ...

  10. 【原】Storm实战

    3.Storm实战 如何新建一个Storm 项目 本文简要概括如何新建一个Storm项目,步骤如下: 1.添加Storm 相关jar添加到类路径上. 2.如果使用多语言特性,将多语言实现的目录加到cl ...