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 ...
随机推荐
- HDU 5407 CRB and Candies
题意:给一个正整数k,求lcm((k, 0), (k, 1), ..., (k, k)) 解法:在oeis上查了这个序列,得知答案即为lcm(1, 2, ..., k + 1) / (k + 1),而 ...
- Binary Tree Level Order Traversal java实现
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...
- redis错误汇总
1.redis因为内存不够而启动失败 Microsoft Open Tech group 在 GitHub上开发了一个REDIS Win64的版本,项目地址是:https://github.com/M ...
- HDU 3333-Turing Tree(BIT好题)
题意: 给你n个数的序列a,q个询问,每个询问给l,r,求在下标i在[l,r]的区间内不含重复数的和 分析: 这类题目觉得很好,很练思维,觉得不太好做. 用BIT维护和,我们可以从前向后扫一遍序列,当 ...
- Jmeter教程
博客园 http://www.cnblogs.com/yangxia-test/category/431240.html 1)分析能力没有LoadRunner详细 2)jmeter不支持IP欺骗,而L ...
- Selenium2Library系列 keywords 之 _SelectElementKeywords 之 _get_values_for_options(self, options)
def _get_values_for_options(self, options): values = [] for option in options: values.append(option. ...
- 学习笔记 - 深究Bitmap压缩避免OOM的核心inSampleSize的最佳取值
/** * 测试代码,通过在SDCard根目录放置几种不同大小的图片, 来自动测试压缩方式是否有效同时看是否会内存不够. * * @since * By:AsionTang * At:2014年3月2 ...
- csv文件与DataTable互相导入处理
封装处理下,以后项目用到可以直接使用,比较简单. 1.首先看封装好的类 using System; using System.Data; using System.IO; using System.T ...
- 【windows核心编程】一个HOOK的例子
一.应用场景 封装一个OCX控件,该控件的作用是来播放一个视频文件,需要在一个进程中放置四个控件实例. 由于控件是提供给别人用的,因此需要考虑很多东西. 二.考虑因素 1.控件的父窗口resize时需 ...
- 【原】Storm实战
3.Storm实战 如何新建一个Storm 项目 本文简要概括如何新建一个Storm项目,步骤如下: 1.添加Storm 相关jar添加到类路径上. 2.如果使用多语言特性,将多语言实现的目录加到cl ...