POJ 3076 Sudoku (dancing links)
题目大意:
16*16的数独。
思路分析:
想说的就是dancing links 的行是依照
第一行第一列填 1
第一行第二列填 2
……
第一行第十五列填15
第一行第二列填 1
……
第二行。。。。
列的纺织则是
第一行放1,第一行放2,。。第十六行放16.。。第一列放1.。第一列放2.。。第十六列放16.。第一块区域放1 。。。。然后在最后81位就是放自己的位置,准确的说就是 r*m+c。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define maxn 16*16*16*16*16*4+5
#define inf 0x3f3f3f3f
using namespace std; int n=16*16*9,m=16*16*4,p;
int map[16*16*16+5][16*16*4+5];
int L[maxn],R[maxn],D[maxn],U[maxn],S[maxn],O[maxn],col[maxn],row[maxn],head,cnt;
int num; void dancing_links_init()
{
head=0;
memset(S,0,sizeof S);
for(int i=head;i<=m;i++)
{
R[i]=(i+1)%(m+1);
L[i]=(i-1+m+1)%(m+1);
U[i]=D[i]=i;
}
cnt=m+1;
for(int i=1;i<=n;i++)
{
int rowh=-1;
for(int j=1;j<=m;j++)
{
if(map[i][j])
{
S[j]++;
U[cnt]=U[j];
D[U[j]]=cnt;
U[j]=cnt;
D[cnt]=j;
row[cnt]=i;
col[cnt]=j;
if(rowh==-1)
{
L[cnt]=R[cnt]=cnt;
rowh=cnt;
}
else
{
L[cnt]=L[rowh];
R[L[rowh]]=cnt;
R[cnt]=rowh;
L[rowh]=cnt;
}
cnt++;
}
}
}
}
void Remove(const 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[col[j]];
}
}
}
void Resume(const int &c)
{
for(int i=U[c];i!=c;i=U[i])
{
for(int j=L[i];j!=i;j=L[j])
{
++S[col[j]];
U[D[j]]=j;
D[U[j]]=j;
}
}
L[R[c]]=c;
R[L[c]]=c;
}
bool dfs(const int &k)//可行解
{
if(head==R[head])
{
sort(O,O+256);
for(int i=0;i<256;i++)
{
printf("%c",O[i]-i*16+'A'-1);
if(i%16==15)puts("");
}
puts("");
return true;
}
int mx=inf,cur=0;
for(int t=R[head];t!=head;t=R[t])
{
if(S[t]<mx)
{
mx=S[t];
cur=t;
}
}
Remove(cur);//依据開始的时候的推断条件,能够知道是一列一列的选择
for(int i=D[cur];i!=cur;i=D[i])//这里就是先选择列
{//然后去选择删除哪一行是覆盖了这列的
O[k]=row[i];
for(int j=R[i];j!=i;j=R[j])
{
Remove(col[j]);
}
if(dfs(k+1))return true;
for(int j=L[i];j!=i;j=L[j])
{
Resume(col[j]);
}
}
Resume(cur);
return false;
}
/*
void dfs(const int &k)//最优解
{
if(R[head]==head)
{
if(k<num)num=k;
return;
}
if(k>=num)return;
int mx=inf,cur=0;
for(int t=R[head];t!=head;t=R[t])
{
if(S[t]<mx)
{
mx=S[t];
cur=t;
}
}
Remove(cur);
for(int i=D[cur];i!=cur;i=D[i])
{
for(int j=R[i];j!=i;j=R[j])
{
Remove(col[j]);
}
dfs(k+1);
for(int j=L[i];j!=i;j=L[j])
{
Resume(col[j]);
}
}
Resume(cur);
}
*/
char tmp[16][1111];
char str[1111];
int main()
{
while(scanf("%s",tmp[0])!=EOF)
{
for(int i=1;i<16;i++)scanf("%s",tmp[i]);
int cnt=0;
for(int i=0;i<16;i++)
for(int j=0;j<16;j++)
str[cnt++]=tmp[i][j]; memset(map,0,sizeof map);
int len=cnt;
for(int i=0;i<len;i++)
{
int r=i/16;
int c=i-r*16;
int base=(r*16+c)*16; if(str[i]=='-')
{
for(int k=1;k<=16;k++)
{
map[base+k][r*16+k]=1;
map[base+k][256+c*16+k]=1;
map[base+k][256+256+16*(4*(r/4)+(c/4))+k]=1;
map[base+k][256*3+r*16+c+1]=1;
}
}
else
{
int k=str[i]-'A'+1;
map[base+k][r*16+k]=1;
map[base+k][256+c*16+k]=1;
map[base+k][256+256+16*(4*(r/4)+(c/4))+k]=1;
map[base+k][256+256+256+r*16+c+1]=1;
}
}
dancing_links_init();
dfs(0);
}
return 0;
}
POJ 3076 Sudoku (dancing links)的更多相关文章
- poj 3074 Sudoku(Dancing Links)
Sudoku Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8152 Accepted: 2862 Descriptio ...
- POJ3074 Sudoku —— Dancing Links 精确覆盖
题目链接:http://poj.org/problem?id=3074 Sudoku Time Limit: 1000MS Memory Limit: 65536K Total Submissio ...
- (简单) POJ 3076 Sudoku , DLX+精确覆盖。
Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...
- POJ 3074 Sudoku (Dacing Links)
推荐一个写数独很好的博客:http://www.cnblogs.com/grenet/p/3163550.html 主要是把九宫格里的元素换到矩阵里面再求解dancing links 网上找的一模版 ...
- POJ 3076 Sudoku DLX精确覆盖
DLX精确覆盖模具称号..... Sudoku Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 4416 Accepte ...
- POJ 3076 Sudoku
3076 思路: dfs + 剪枝 首先,如果这个位置只能填一种字母,那就直接填 其次,如果对于每一种字母,如果某一列或者某一行或者某一块只能填它,那就填它 然后,对于某个位置如果不能填字母了,或者某 ...
- POJ 3076 SUKODU [Dangcing Links DLX精准覆盖]
和3074仅仅有数目的不同,3074是9×9.本来想直接用3074的.然后MLE,,,就差那么20M的空间,,. 从这里学习到了解法: http://www.cnblogs.com/ylfdrib/a ...
- HDU 3111 Sudoku ( Dancing Links 精确覆盖模型 )
推荐两篇学DLX的博文: http://bbs.9ria.com/thread-130295-1-1.html(这篇对DLX的工作过程演示的很详细) http://yzmduncan.iteye.co ...
- 算法实践——舞蹈链(Dancing Links)算法求解数独
在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dancing Links)算法求解精确覆盖问题. 本文介绍该算法的实际运用,利用舞蹈链(Dancin ...
随机推荐
- HDOJ 5088 Revenge of Nim II 位运算
位运算.. .. Revenge of Nim II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- Spring笔记 - Bean xml装配
命名空间表 aop Provides elements for declaring aspects and for automatically proxying @AspectJannotated c ...
- OC-多线程安全隐患及一般解决办法
1.多线程的安全隐患1.1>一块资源可能被多个线程共享,也就是多个线程可能会访问同一块资源,如多个线程访问同一个对象,变量,文件等当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题1. ...
- Jquery Mobile转场特效之slide | 小小iPhone开发
Jquery Mobile转场特效之slide | 小小iPhone开发 2012 Jquery Mobile转场特效之slide 作者:小小 发布:2012-12-12 14:03 分类:j ...
- C++断言assert
assert宏是在标准库中提供的.它在库文件<cassert>中声明,它能够在程序中測试逻辑表达式,假设指定的逻辑表达式是false,assert()就会终止程序,并显示诊断消息.关闭断言 ...
- tomcat加载时报The web application [/dmscs] created a ThreadLocal with key of type
严重: The web application [/dmscs] created a ThreadLocal with key of type [com.opensymphony.xwork2.inj ...
- 用python将SQL格式文件改成自己想要的格式
INSERT INTO TTT (NSAME, ID, AGE) VALUES ('AAA', '201023210816', '22'); 将上面的SQL格式改成以下的格式 AAA|20102321 ...
- Swift - 跑酷游戏开发(SpriteKit游戏开发)
一,下面演示了如何开发一个跑酷游戏,实现的功能如下: 1,平台工厂会不断地生成平台,并且向左移动.当平台移出游戏场景时就可将其移除. 2,生成的平台宽度随机,高度随机.同时短平台踩踏的时候会下落. 3 ...
- C++学习之路—继承与派生(三):多重继承与虚基类
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 多重继承是指一个派生类有两个或多个基类.例如,有 ...
- 终于懂了:TWinControl.DefaultHandler里的CallWindowProc(FDefWndProc)还挺有深意的,TButton对WM_PAINT消息的处理就是靠它来处理的(以前不明白为什么总是要调用inherited,其实就是没有明白TWinControl.DefaultHandler的真正用处)
我忽然发现:TButton既没有处理WM_PAINT,又没有Paint()或者PaintWindow(),那么它是什么时候被绘制的? Form1上放2个TButton,然后设置代码: procedur ...