舞蹈链 - Sudoku
来源:互联网 发布:手机wifi服务器端口 编辑:程序博客网 时间:2024/06/10 09:04
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=65998#problem/F
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=65998#problem/G
bin神专题里的两个数独问题, 后面还有一个变形的数独(不是普通的九宫格 十六宫格)
这里一个是九宫格, 一个是十六宫格的数独…
具体的构图在前一篇的那里有说到一位菊苣的blog, 他的介绍写的非常好, 可以去看一下..
主要是4个约束条件:
- 每一个格子都要放一个数
- 每一行要有9种数字,不许重复
- 每一列要有9种数字,不许重复
- 每一个宫要有9种数字,不许重复
如果是16的就直接把上面改成16..
转化的和构图的话, 还是看菊苣的介绍吧..我就重复发明轮子了..
九宫格的: POJ3074
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<string>#include<stack>#include<queue>#include<vector>#include<map>#include<set>#include<iostream>#define pb push_back#define INF 0x3f3f3f3fusing namespace std;typedef unsigned long long ULL;typedef long long LL;const int mod = 1000000007;const int N = 9; //3*3数独const int MaxN = N*N*N + 10;const int MaxM = N*N*4 + 10;const int maxnode = MaxN*4 + MaxM + 10;char g[MaxN];struct DLX { int n,m,size; int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode]; int H[MaxN],S[MaxM]; int ansd,ans[MaxN]; void init(int _n,int _m) { n = _n; m = _m; for(int i = 0;i <= m;i++) { S[i] = 0; U[i] = D[i] = i; L[i] = i-1; R[i] = i+1; } R[m] = 0; L[0] = m; size = m; for(int i = 1;i <= n;i++)H[i] = -1; } void Link(int r,int c) { ++S[Col[++size]=c]; Row[size] = r; D[size] = D[c]; U[D[c]] = size; U[size] = c; D[c] = size; if(H[r] < 0)H[r] = L[size] = R[size] = size; else { R[size] = R[H[r]]; L[R[H[r]]] = size; L[size] = H[r]; R[H[r]] = size; } } 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[Col[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[Col[U[D[j]]=D[U[j]]=j]]; L[R[c]] = R[L[c]] = c; } bool Dance(int d) { if(R[0] == 0) { for(int i = 0;i < d;i++)g[(ans[i]-1)/9] = (ans[i]-1)%9 + '1'; for(int i = 0;i < N*N;i++)printf("%c",g[i]); printf("\n"); return true; } int c = R[0]; for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i; remove(c); for(int i = D[c];i != c;i = D[i]) { ans[d] = Row[i]; for(int j = R[i];j != i;j = R[j])remove(Col[j]); if(Dance(d+1))return true; for(int j = L[i];j != i;j = L[j])resume(Col[j]); } resume(c); return false; }};inline void get(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k){ r = (i*N+j)*N + k; c1 = i*N + j+1; c2 = N*N+i*N+k; c3 = N*N*2+j*N+k; c4 = N*N*3+((i/3)*3+(j/3))*N+k;}DLX sol;char s[100];void solve() { while(~scanf("%s", s)){ if(!strcmp(s, "end")) return ; sol.init(N*N*N, N*N*4); int r, c1, c2, c3, c4; for(int i=0; i<N; i++) for(int j=0; j<N; j++) for(int k=1; k<=N; k++) if(s[i*N+j] == '.' || s[i*N+j] == '0' + k){ get(r, c1, c2, c3, c4, i, j, k); sol.Link(r, c1); sol.Link(r, c2); sol.Link(r, c3); sol.Link(r, c4); } sol.Dance(0); }}int main(void) {#ifdef DK freopen("/home/dk/桌面/1.in","r",stdin);#endif // DK solve(); return 0;}
十六宫格的: ZOJ 3122
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<string>#include<stack>#include<queue>#include<vector>#include<map>#include<set>#include<iostream>#define pb push_back#define INF 0x3f3f3f3fusing namespace std;typedef unsigned long long ULL;typedef long long LL;const int mod = 1000000007;const int N = 16;const int MaxN = N*N*N + 10;const int MaxM = N*N*4 + 10;const int maxnode = MaxN*4 + MaxM + 10;char g[MaxN];struct DLX { int n,m,size; int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode]; int H[MaxN],S[MaxM]; int ansd,ans[MaxN]; void init(int _n,int _m) { n = _n; m = _m; for(int i = 0;i <= m;i++) { S[i] = 0; U[i] = D[i] = i; L[i] = i-1; R[i] = i+1; } R[m] = 0; L[0] = m; size = m; for(int i = 1;i <= n;i++)H[i] = -1; } void Link(int r,int c) { ++S[Col[++size]=c]; Row[size] = r; D[size] = D[c]; U[D[c]] = size; U[size] = c; D[c] = size; if(H[r] < 0) H[r] = L[size] = R[size] = size; else { R[size] = R[H[r]]; L[R[H[r]]] = size; L[size] = H[r]; R[H[r]] = size; } } 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[Col[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[Col[U[D[j]]=D[U[j]]=j]]; L[R[c]] = R[L[c]] = c; } bool Dance(int d) { //printf("r->%d d : %d\n", R[0], d); if(R[0] == 0) { ansd = d; for(int i = 0; i < d; i++) g[(ans[i]-1)/N] = (ans[i]-1)%N + 'A'; for(int i = 0; i < N; i++) { for(int j=0; j<N; j++) printf("%c", g[i*N+j]); puts(""); } return true; } int c = R[0]; //printf("c : %d down : %d\n", c, D[c]); for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]){ c = i; //printf("i : %d S[i] : %d\n", i, S[i]); } //printf("c : %d down : %d\n", c, D[c]); remove(c); for(int i = D[c];i != c;i = D[i]) { ans[d] = Row[i]; for(int j = R[i];j != i;j = R[j])remove(Col[j]); if(Dance(d+1)) return true; for(int j = L[i];j != i;j = L[j])resume(Col[j]); } resume(c); return false; }};inline void get(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k){ r = (i*N+j)*N + k; c1 = i*N+j+1; c2 = N*N+i*N+k; c3 = N*N*2+j*N+k; c4 = N*N*3+((i/4)*4+(j/4))*N+k;}DLX dlx;char s[20][100];inline int read() { for(int i=0; i<N; i++) if(scanf("%s", s[i]) == EOF) return false; //for(int i=0; i<N; i++) printf("%s\n", s[i]); return true;}void solve() { int first = 1; while(read()){ if(first) first = 0; else puts(""); dlx.init(N*N*N, N*N*4); int r, c1, c2, c3, c4; for(int i=0; i<N; i++) for(int j=0; j<N; j++) for(int k=1; k<=N; k++) if(s[i][j] == '-' || s[i][j] == 'A' + k-1){ get(r, c1, c2, c3, c4, i, j, k); dlx.Link(r, c1); dlx.Link(r, c2); dlx.Link(r, c3); dlx.Link(r, c4); //printf("r:%d c1:%d c2:%d c3:%d c4:%d\n", r, c1, c2, c3, c4); } dlx.Dance(0); }}int main(void) {#ifdef DK freopen("/home/dk/桌面/1.in","r",stdin);#endif // DK solve(); return 0;}
0 0
- 舞蹈链 - Sudoku
- POJ 3074 Sudoku 舞蹈链
- 【Dancing Links舞蹈链】poj 3076 Sudoku
- poj3074 Sudoku--舞蹈链数独
- poj3076 Sudoku--舞蹈链数独
- 舞蹈链
- hdu 4069 舞蹈链
- 舞蹈链详解
- 舞蹈链2
- 舞蹈
- 舞蹈链模板题汇总
- HDU 3335(舞蹈链)
- HDU 5046(舞蹈链)
- POJ 3074&&3076 舞蹈链
- dancing links(舞蹈链)
- 舞蹈链模板 Dancing Links
- dancing links - 舞蹈的链表
- 舞蹈链备忘:解决精确覆盖问题
- 杭电 1896 Stones 队列 附题目翻译
- Struts2中result配置中常见的几种视图转发类型
- Java反射—运用反射生成jdk动态代理
- 图结构练习——最小生成树
- Qt窗口中的一些小技术总结
- 舞蹈链 - Sudoku
- USACO:2.2.2 Subset Sums 集合和
- iOS的文件管理——沙盒(sandbox)
- office 2013错误1402
- 关于拓扑排序
- 云计算 杂谈
- tomcat的目录结构
- bzoj1003【zjoi2006】物流运输trans
- leetcode241 java递归写法,重在思想