题目大意:

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. 通过DWR简化AJAX开发

    DWR(Direct Web Remoting)是一个WEB远程调用框架,采取了一个类似AJAX的新方法来动态生成基于JAVA类的JavaScript代码.这样WEB开发人员就可以在JavaScrip ...

  2. D16Pascal的编译器和IDE

    https://github.com/Memnarch/D16Pascal https://github.com/Memnarch/D16IDE https://github.com/Memnarch ...

  3. 获取wpf datagrid当前被编辑单元格的内容

    原文 获取wpf datagrid当前被编辑单元格的内容 确认修改单元个的值, 使用到datagrid的两个事件 开始编辑事件 BeginningEdit="dataGrid_Beginni ...

  4. Android Studio经常使用操作技巧(不断更新)

    这段时间一直在用Android Studio做一些Demo的开发.一開始从Eclipse中转向这个开发工具,各种不适应,希望此博文能够一直更新.还有网友能够分享出自己方便更好更快开发的一些技巧. 首先 ...

  5. Ural1109_Conference(二分图最大匹配/匈牙利算法/网络最大流)

    解题报告 二分图第一题. 题目描写叙述: 为了參加即将召开的会议,A国派出M位代表,B国派出N位代表,(N,M<=1000) 会议召开前,选出K队代表,每对代表必须一个是A国的,一个是B国的; ...

  6. openstack中Nova组件images的全部python API 汇总

    感谢朋友支持本博客.欢迎共同探讨交流,因为能力和时间有限,错误之处在所难免.欢迎指正! 假设转载,请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...

  7. Vmdk文件如何使用,vmdk导入虚拟机VMware8.0教程

    一.打开虚拟机VMware Workstation8.0,点击新建虚拟机. 二.进入虚拟机向导,选择自定义. 三.这里保持默认即可. 四.这里选择“我以后安装操作系统”. 五.这里选择Windows ...

  8. 【ASP.NET Web API教程】3.3 通过WPF应用程序调用Web API(C#)

    原文:[ASP.NET Web API教程]3.3 通过WPF应用程序调用Web API(C#) 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的 ...

  9. exception in thread main java.lang.NoClassDefFoundError wrong name解决方法

    当不含包层次的HelloWorld.java代码(此时程序运行正常) public class HelloWorld{ public static void main(String[] args)   ...

  10. Exception in thread "main" java.net.BindException: Address already in use: JVM_Bind

    Exception in thread "main" java.net.BindException: Address already in use: JVM_Bind    at ...