POJ 3074 Sudoku (Dancing Links)
传送门: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)的更多相关文章
- 算法实践——舞蹈链(Dancing Links)算法求解数独
在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dancing Links)算法求解精确覆盖问题. 本文介绍该算法的实际运用,利用舞蹈链(Dancin ...
- 转载 - 算法实践——舞蹈链(Dancing Links)算法求解数独
出处:http://www.cnblogs.com/grenet/p/3163550.html 在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dan ...
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 例如:如下的矩阵 就包含了这样一个集合(第1.4.5行) 如何利用给定的矩阵求出相应的行的集合 ...
- [转] 舞蹈链(Dancing Links)——求解精确覆盖问题
转载自:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个 ...
- 算法帖——用舞蹈链算法(Dancing Links)求解俄罗斯方块覆盖问题
问题的提出:如下图,用13块俄罗斯方块覆盖8*8的正方形.如何用计算机求解? 解决这类问题的方法不一而足,然而核心思想都是穷举法,不同的方法仅仅是对穷举法进行了优化 用13块不同形状的俄罗斯方块(每个 ...
- 【POJ3740】Easy Finding DLX(Dancing Links)精确覆盖问题
题意:多组数据,每组数据给你几行数,要求选出当中几行.使得每一列都有且仅有一个1.询问是可不可行,或者说能不能找出来. 题解:1.暴搜.2.DLX(Dancing links). 本文写的是DLX. ...
- 转载 - 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
出处:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 ...
- 【POJ3074】Sudoku DLX(Dancing Links)
数独就要DLX,不然不乐意. 数独的DLX构造:9*9个点每一个点有9种选择,这构成了DLX的729行,每行.列.阵有限制,均为9行(/列/阵),然后每行(/列/阵)都有九种数的情况.于是就有了3*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 ...
随机推荐
- group by调优的一些测试
表结构信息: mysql> show create table tb\G*************************** 1. row ************************** ...
- xp重装系统后恢复Linux启动
我的电脑----右键-----属性----高级----启动与恢复故障----设置编辑 [boot loader]timeout=3default=multi(0)disk(0)rdisk(0)part ...
- java web 学习九(通过servlet生成验证码图片)
一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:
- 【LeetCode 213】House Robber II
This is an extension of House Robber. After robbing those houses on that street, the thief has found ...
- 《Python CookBook2》 第四章 Python技巧 - 若列表中某元素存在则返回之 && 在无须共享引用的条件下创建列表的列表
若列表中某元素存在则返回之 任务: 你有一个列表L,还有一个索引号i,若i是有效索引时,返回L[i],若不是,则返回默认值v 解决方案: 列表支持双向索引,所以i可以为负数 >>> ...
- selenium打开带有扩展的chrome
每当用跑用例失败的时候,第一反应就是查看元素定位是不是正确,帮助定位的扩展是必不可少的,但是selenium一般打开的是不带扩展的干净的浏览器,如果操作步骤很长的话,就得手动去执行直到那一步去检查元素 ...
- springmvc基础知识
springmvc框架,类似于struts,主要用于MVC的控制层 spring的简单配置(非注解): spring-mvc.xml文件(springMVC框架的基本文件) web.xml文件 ja ...
- STL底层数据结构实现
C++ STL 的实现: 1.vector 底层数据结构为数组 ,支持快速随机访问 2.list 底层数据结构为双向链表,支持快速增删 3.deque 底层 ...
- 如果你喜欢Python 那么你不得不知的几个开源项目
1.Trac Trac拥有强大的bug管理 功能,并集成了Wiki 用于文档管理.它还支持代码管理工具Subversion ,这样可以在 bug管理和Wiki中方便地参考程序源代码. Trac有着比较 ...
- vmware ubuntu14.04虚拟机不能正常拷贝文件到windows且不能自适应虚拟机屏幕窗口自动变化的解决办法
纠结于这个问题了半天.一直重复安装不同版本的vmare-tools, 一直没有任何效果.进入到/usr/bin/ 目录使用ll vm* 查看,发现和别的不同的是没有vmware-toolbox-cmd ...