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 ...
随机推荐
- BitHacks--位操作技巧
---------------------------------------------------------------------------------------------------- ...
- c++ split模板实现
模板实现,重载+6: template<typename _Elem, typename _Fty> inline void split(const _Elem* s, const _El ...
- android 打包 /${zipalign}" error=2, No such file or directory
当我更新完android L proview之后我的打包出问题了,报错/${zipalign}" error=2, No such file or directory 排查了一下午才知道 近 ...
- Spring 从零開始-05
最终能到Spring的AOP编程了,AOP的概念特别的多.所以须要你在開始之前有点了解,然后通过代码慢慢学习! - 切面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象.事务管 ...
- JQuery AJAX Demo
JQuery AJAX Demo APP发展集团:347072638(HTML5,APP) 1.先看一个JQuery AJAX Demo HTML端: <!DOCTYPE html PUBLIC ...
- linux命令:scp
有时候ftp被禁用了, 就用scp替代; 命令行: scp from to_user@to_ip:dir_to/file_name 执行该命令之后,按照提示输入to_host的登陆密码即可. scp ...
- ABAP 向上取整和向下取整 CEIL & FLOOR
下面是一段关于CEIL 和 FLOOR 的代码 DATA:a TYPE mseg-menge, b TYPE mseg-menge, c TYPE mseg-menge. a = '1.36'. b ...
- Ubuntu_文件夹名字转化成英文
打开终端命令行输入: export LANG=en_US xdg-user-dirs-gtk-update 之后重启,就看到中文的文件夹变成英文的了 想要换回中文的输入: export LANG=zh ...
- HDU 4893 Wow! Such Sequence!(2014年多校联合 第三场 G)(线段树)
磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add 把d加到第k个数上去2 ...
- C++运算符重载的方法
运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算.也就是说,运算符重载是通过定义函数实现的. 运算符重载实质上是函数的重载 重载运算符的函 ...