【Dancing Links舞蹈链】poj 3076 Sudoku
来源:互联网 发布:如何进入淘宝vip商场 编辑:程序博客网 时间:2024/04/25 18:42
Source : poj 3076 Sudoku
http://poj.org/problem?id=3076
Problem Description
A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells are filled with letters from A to P (the first 16 capital letters of the English alphabet), as shown in figure 1a. The game is to fill all the empty grid cells with letters from A to P such that each letter from the grid occurs once only in the line, the column, and the 4x4 square it occupies. The initial content of the grid satisfies the constraints mentioned above and guarantees a unique solution.
Write a Sudoku playing program that reads data sets from a text file.
Input
Each data set encodes a grid and contains 16 strings on 16 consecutive lines as shown in figure 2. The i-th string stands for the i-th line of the grid, is 16 characters long, and starts from the first position of the line. String characters are from the set {A,B,…,P,-}, where – (minus) designates empty grid cells. The data sets are separated by single empty lines and terminate with an end of file.
Output
The program prints the solution of the input encoded grids in the same format and order as used for input.
题意
16×16的数独游戏,不过数字1~9变成A~P了!
示例
Sample Input
–A—-C—–O-I
-J–A-B-P-CGF-H-
–D–F-I-E—-P-
-G-EL-H—-M-J–
—-E—-C–G—
-I–K-GA-B—E-J
D-GP–J-F—-A–
-E—C-B–DP–O-
E–F-M–D–L-K-A
-C——–O-I-L-
H-P-C–F-A–B—
—G-OD—J—-H
K—J—-H-A-P-L
–B–P–E–K–A-
-H–B–K–FI-C–
–F—C–D–H-N-
Sample Output
FPAHMJECNLBDKOGI
OJMIANBDPKCGFLHE
LNDKGFOIJEAHMBPC
BGCELKHPOFIMAJDN
MFHBELPOACKJGNID
CILNKDGAHBMOPEFJ
DOGPIHJMFNLECAKB
JEKAFCNBGIDPLHOM
EBOFPMIJDGHLNKCA
NCJDHBAEKMOFIGLP
HMPLCGKFIAENBDJO
AKIGNODLBPJCEFMH
KDEMJIFNCHGAOPBL
GLBCDPMHEONKJIAF
PHNOBALKMJFIDCEG
IAFJOECGLDPBHMNK
思路
DLX算法在数独问题中的应用
精确覆盖问题之DLX算法
【图文解释】 http://www.cnblogs.com/grenet/p/3145800.html
【论文1】http://www.docin.com/p-387677023.html
【论文2】http://wenku.baidu.com/link?url=iNBiCQxuADYjU93J4qo6rUJQ21ZczH3fVqq6Peqp_2aAzWTEOfzTPuzh8eCtAoAXBaiE-sglg4BOfL6ultIItffmqHj0bHgPW-6qCXF7zyG
数独问题转换为精确覆盖问题(N*N*N行N*N*4列0-1矩阵),DLX算法+刘汝佳模板(参见论文2和大白书P406)
In addition : poj 3074、poj 2676、swjtu_OJ 2095题目都可以用DLX解决
参考代码 poj 3076
/*====================================*\|* 舞蹈链 DLX *|\*====================================*//*Author:Hacker_vision*/#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<vector>#include<map>#include<climits>#define clr(k,v) memset(k,v,sizeof(k))#define ll long long#define eps 1e-8using namespace std;const int SLOT = 0;const int ROW = 1;const int COL = 2;const int SUB = 3;const int N = 16;const int M = 4;const int maxr = N*N*N + 10;//行数const int maxn = N*N*4 + 10;//列数const int maxnode = maxr*maxn + 10;//总节点数char g[20][20];struct DLX{ int n,sz;//列数,节点总数 int S[maxn];//各列节点数 int row[maxnode],col[maxnode];//各节点行列编号 int L[maxnode],R[maxnode],U[maxnode],D[maxnode];//十字链表,用数组写的 int ansd,ans[maxr];//解 void init(int n){ //n是列数 this->n = n; //虚拟节点 for(int i = 0; i <= n; ++ i){ U[i] = i;D[i] = i;L[i] = i - 1;R[i] = i + 1; } R[n] = 0;L[0] = n; sz = n + 1; memset(S,0,sizeof(S)); } void addRow(int r,vector<int>columns){ int first= sz; for(int i = 0; i < columns.size(); ++ i){ int c = columns[i]; L[sz] = sz - 1;R[sz] = sz + 1;D[sz] = c;U[sz] = U[c]; D[U[c]] = sz;U[c] = sz; row[sz] = r;col[sz] = c; S[c]++;sz++; } R[sz - 1] = first;L[first] = sz - 1; } //顺着链表A,遍历除s外的其他元素 // #define FOR(i,A,s) for(int i = A[s]; i != s;i = A[i]) 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 restore(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(int d){ if(R[0] == 0){ ansd = d; return true; } //找S的最小列 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(dfs(d+1)) return true; for(int j = L[i]; j != i; j = L[j]) restore(col[j]); } restore(c); return false; } bool solve(vector<int>&v){ v.clear(); if(!dfs(0)) return false; for(int i = 0; i < ansd; ++ i) v.push_back(ans[i]); return true; }};//行、列的统一编解码函数。从1开始编号int encode(int a,int b,int c){ return a*N*N + b*N + c + 1;}void decode(int code,int& a,int& b,int& c){ code--; c = code%N; code/=N; b = code%N; code/=N; a = code;}DLX dlx;int main(){ #ifndef ONLINE_JUDGE freopen("input.txt","r",stdin); #endif // ONLINE_JUDGE while(scanf("%s",g[0]) == 1){ for(int i = 1;i < 16;++ i) scanf("%s",g[i]); dlx.init(N*N*4);//列数 for(int r = 0; r < N; ++ r) for(int c = 0; c < N; ++ c) for(int v = 0; v < N; ++ v) if(g[r][c] == '-'||g[r][c] == 'A' + v){ vector<int>columns; columns.push_back(encode(SLOT,r,c));//列数分四种情况 columns.push_back(encode(ROW,r,v)); columns.push_back(encode(COL,c,v)); columns.push_back(encode(SUB,(r/M)*M+c/M,v)); dlx.addRow(encode(r,c,v),columns); } vector<int>ans; dlx.solve(ans); for(int i = 0; i <ans.size(); ++ i){ int r,c,v; decode(ans[i],r,c,v); g[r][c] = 'A' + v; } for(int i = 0; i < N; ++ i) printf("%s\n",g[i]); puts("");//防PE } return 0;}
- 加粗
Ctrl + B
- 斜体
Ctrl + I
- 引用
Ctrl + Q
- 插入链接
Ctrl + L
- 插入代码
Ctrl + K
- 插入图片
Ctrl + G
- 提升标题
Ctrl + H
- 有序列表
Ctrl + O
- 无序列表
Ctrl + U
- 横线
Ctrl + R
- 撤销
Ctrl + Z
- 重做
Ctrl + Y
- 【Dancing Links舞蹈链】poj 3076 Sudoku
- poj 3076 Sudoku //Dancing Links
- POJ 3076 Sudoku (dancing links)
- POJ 3074,3076,2676 数独 Dancing Links舞蹈链
- poj 3076 Sudoku(Dancing Links)
- dancing links(舞蹈链)
- 舞蹈链模板 Dancing Links
- poj 3074 Sudoku(Dancing Links)
- dancing links - 舞蹈的链表
- 舞蹈链(Dancing Links)算法
- POJ 3074 Sudoku (Dancing Links)
- poj 3704 Sudoku(Dancing Links)
- POJ3074 Sudoku(Dancing Links)
- POJ 3074 Sudoku 舞蹈链
- DLX Dancing Links X Algorithm 舞蹈链 学习总结
- dancing links 算法学习小记 Poj 3074 Sudoku (数独)
- POJ 3074 Sudoku(数独|Dancing Links精确覆盖)
- dancing links 算法 解 Sudoku
- gui界面开发演示
- ASP.NET MVC的过滤器
- 重写hashCode方法
- 条款05 了解c++默默编写并调用哪些函数。。。
- Java 线程的suspend()和stop()不安全的原因
- 【Dancing Links舞蹈链】poj 3076 Sudoku
- LeetCode Problem:Two Sum
- Shiny应用基础(6):数据响应的触发与阻止
- 2014-2015 ACM-ICPC, Asia Xian Regional Contest C – The Problem Needs 3D Arrays(最大密度子图)
- Git学习第一天:安装Git并创建第一个仓库
- J2SE—线程基础知识积累
- 【codechef】The Warehouse(灵活题)
- wireshark使用教程(之1)
- NDK开发之ndk-build命令详解