题目大意:

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)的更多相关文章

  1. poj 3074 Sudoku(Dancing Links)

    Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8152   Accepted: 2862 Descriptio ...

  2. POJ3074 Sudoku —— Dancing Links 精确覆盖

    题目链接:http://poj.org/problem?id=3074 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissio ...

  3. (简单) POJ 3076 Sudoku , DLX+精确覆盖。

    Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells ...

  4. POJ 3074 Sudoku (Dacing Links)

    推荐一个写数独很好的博客:http://www.cnblogs.com/grenet/p/3163550.html 主要是把九宫格里的元素换到矩阵里面再求解dancing links 网上找的一模版 ...

  5. POJ 3076 Sudoku DLX精确覆盖

    DLX精确覆盖模具称号..... Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 4416   Accepte ...

  6. POJ 3076 Sudoku

    3076 思路: dfs + 剪枝 首先,如果这个位置只能填一种字母,那就直接填 其次,如果对于每一种字母,如果某一列或者某一行或者某一块只能填它,那就填它 然后,对于某个位置如果不能填字母了,或者某 ...

  7. POJ 3076 SUKODU [Dangcing Links DLX精准覆盖]

    和3074仅仅有数目的不同,3074是9×9.本来想直接用3074的.然后MLE,,,就差那么20M的空间,,. 从这里学习到了解法: http://www.cnblogs.com/ylfdrib/a ...

  8. HDU 3111 Sudoku ( Dancing Links 精确覆盖模型 )

    推荐两篇学DLX的博文: http://bbs.9ria.com/thread-130295-1-1.html(这篇对DLX的工作过程演示的很详细) http://yzmduncan.iteye.co ...

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

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

随机推荐

  1. 真机iOS SDK升级后xcode不能进行真机调试 怎么办

    今天升级了一下iPod的SDK到iOS8,xcode仅仅能支持到7.1,真机调试遇到问题???以下是解决的方法! 找到xcode,点击右键.打开显示包内容,按路径Contents/Develpoer/ ...

  2. codeforces #267 C George and Job(DP)

    职务地址:http://codeforces.com/contest/467/problem/C 太弱了..这题当时都没做出来..思路是有的,可是自己出的几组数组总是过不去..今天又又一次写了一遍.才 ...

  3. 手把手教你安装QT集成开发环境(操作系统为ubuntu10.04)

    在安装QT集成开发工具包之前需要先安装build-essential和libncurses5-dev这两个开发工具和库,libncurses5-dev库是一个在Linux/Unix下广泛应用的图形函数 ...

  4. 12.5.3 UNIVERSAL:最终的祖先类:

    <pre name="code" class="html">12.5.3 UNIVERSAL:最终的祖先类: 你可以把 UNIVERSAL 看作最终 ...

  5. Python学习笔记 — 函数

    函数是对程序逻辑进行结构化或过程化的一种编程方法.函数具有两个方面的意义:1)将代码分块,易于管理和阅读:2)最大化代码复用和最小化代码冗余,节省空间,有助于保持一致性. 1. 函数定义 Python ...

  6. swift 有些语法还是不支持。

    <pre name="code" class="html">"func hasAnyMatches(list: Int[], condit ...

  7. java常用内存设置

    Java虚拟机具有一个堆,是运行时的数据区域,所有类实例和数组内存均从此处分配.堆是在java虚拟机启动时创建的. 堆是留给开发人员用的内存区域.非堆就是JVM留给自己用的(方法区,JVM内部处理或优 ...

  8. 图解C#_事件

    概述 今天用来演示事件的例子是模拟实现一个文件下载类,在这个类中我将定义一个DownLoad事件,这个事件用来在文件下载的过程中,向订阅这个事件的用户发出消息,而这个消息将用DownLoadEvent ...

  9. 微信5.0 Android版飞机大战破解无敌模式手记

    微信5.0 Android版飞机大战破解无敌模式手记 转载: http://www.blogjava.net/zh-weir/archive/2013/08/14/402821.html 微信5.0 ...

  10. 【Ubuntu】升到14,攻克了进入用户后没有菜单条导航栏的问题

    控制台还能够进,用ctrl+alt+f1用老账号登录,用sudo adduser test新建立一个名字叫test的帐号 然后就能够进去了,可能是配置文件坏掉了