Sudoku 数独 (Dancing links)
来源:互联网 发布:中国电信云计算干嘛的 编辑:程序博客网 时间:2024/05/16 02:30
Sudoku
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Description
In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,
Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.
Input
The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.
Output
For each test case, print a line representing the completed Sudoku puzzle.
Sample Input
.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.end
Sample Output
527389416819426735436751829375692184194538267268174593643217958951843672782965341416837529982465371735129468571298643293746185864351297647913852359682714128574936
题意:数独 略
思路:
主要问题就是转化成精确覆盖问题 然后用Dancing links 求解就行了
关键是如何转换 行为决策 列为要求解的问题
列:
r 列 c 列要有值 81列
r 列要有1-9,9*9=81列
c 列要有1-9,9*9=81列
r行c列所处的九宫格要有1-9,9*9=81列
所以共9*9*4列
行:
每行表示一个决策
一行(决策)表示为一个(r, c, v)三元组 表示r行c列填v 所以最多一共有9*9*9行
一行可以完成的是:
1. r行c列有值
2. r行有v
3. c列有v
4.r行c列所处的九宫格有v
所以问题就是 这个01矩阵的精确覆盖问题
#include <cstdio>#include <iostream>#include <vector>#include <algorithm>#include <cstring>#include <string>#include <map>#include <cmath>#include <queue>#include <set>using namespace std;//#define WIN#ifdef WINtypedef __int64 LL;#define iform "%I64d"#define oform "%I64d\n"#elsetypedef long long LL;#define iform "%lld"#define oform "%lld\n"#endif#define S64I(a) scanf(iform, &(a))#define P64I(a) printf(oform, (a))#define REP(i, n) for(int (i)=0; (i)<n; (i)++)#define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++)#define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++)const int INF = 0x3f3f3f3f;const double eps = 10e-9;const double PI = (4.0*atan(1.0));const int maxn = 30000 + 20;int U[maxn], D[maxn], L[maxn], R[maxn], S[maxn];int H[maxn];int COL[maxn], ROW[maxn];int size;int rows;int dataRow[maxn];int dataCol[maxn];int dataV[maxn];int ans[9][9];int opr[maxn][3];void init(int cols) { for(int i=0; i<=cols; i++) { U[i] = D[i] = i; L[i] = i-1; R[i] = i+1; S[i] = 0; } R[cols] = 0; L[0] = cols; size = cols+1; memset(H, -1, sizeof(H));}void insert(int row, int col) { U[size] = U[col]; D[size] = col; D[U[col]] = size; U[col] = size; if(H[row] == -1) { H[row] = R[size] = L[size] = size; } else { int rh = H[row]; R[size] = rh; L[size] = L[rh]; R[L[rh]] = size; L[rh] = size; } S[col]++; COL[size] = col; ROW[size] = row; 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]) { S[COL[j]]--; U[D[j]] = U[j]; D[U[j]] = D[j]; } }}void resume(int c) { L[R[c]] = c; R[L[c]] = c; for(int i=D[c]; i!=c; i=D[i]) { for(int j=L[i]; j!=i; j=L[j]) { S[COL[j]]++; U[D[j]] = j; D[U[j]] = j; } }}bool dfs(int num) { if(R[0] == 0) { for(int i=0; i<num; i++) { int r = opr[i][0]; int c = opr[i][1]; int v = opr[i][2]; ans[r][c] = v; } return true; } int c = R[0]; int mins = S[c]; for(int i=R[0]; i!=0; i=R[i]) if(S[i] < mins) { c = i; mins = S[i]; } remove(c); for(int i=D[c]; i!=c; i=D[i]) { int r = ROW[i]; opr[num][0] = dataRow[r]; opr[num][1] = dataCol[r]; opr[num][2] = dataV[r]; for(int j=R[i]; j!=i; j=R[j]) remove(COL[j]); if(dfs(num+1)) return true; for(int j=L[i]; j!=i; j=L[j]) resume(COL[j]); } resume(c); return false;}void addGrid(int r, int c, int v) { insert(rows, (r-1) * 9 + c); int baseRowV = 81; insert(rows, baseRowV + (r-1) * 9 + v); int baseColV = baseRowV + 81; insert(rows, baseColV + (c-1) * 9 + v); int baseGridV = baseColV + 81; int grid = (r-1) / 3 * 3+ (c-1) / 3; insert(rows, baseGridV + grid * 9 + v); dataRow[rows] = r; dataCol[rows] = c; dataV[rows] = v; rows++;}char puzzle[100];int main() { while(scanf("%s", puzzle) != EOF && strcmp(puzzle, "end")) { int cols = 9*9*4; rows = 1; init(cols); for(int i=0; i<81; i++) { int r = i / 9 + 1; int c = i % 9 + 1; int grid = i / 9 + 1; if(puzzle[i] == '.') { for(int k=1; k<=9; k++) { addGrid(r, c, k); } } else { addGrid(r, c, puzzle[i] - '0'); } } dfs(0); REP1(i, 9) REP1(j, 9) putchar(ans[i][j] + '0'); putchar('\n'); } return 0;}
- Sudoku 数独 (Dancing links)
- POJ 3074 Sudoku(数独|Dancing Links精确覆盖)
- Sudoku 数独 Dancing Links模板
- dancing links 算法学习小记 Poj 3074 Sudoku (数独)
- poj 3074/3076 数独(Dancing Links)
- hdu 4069(Dancing Links数独)
- dancing links-数独的程序解决方案
- poj3074 & 3076 数独 Dancing Links
- poj3074 poj3076 数独问题 dancing links
- 用Dancing Links求解数独
- POJ 2676 数独 Dancing-Links(DLX)
- poj3074/3076 Dancing Links (数独)
- POJ 3074 Sudoku (Dancing Links)
- 【POJ3074】Sudoku DLX(Dancing Links)
- 【POJ3076】Sudoku DLX(Dancing Links)
- poj 3704 Sudoku(Dancing Links)
- csu 1605: Target Sudoku(Dancing Links)
- poj 3076 Sudoku(Dancing Links)
- MCU51单片机uIP协议栈+ENC28J60网卡 移植、应用
- 0706
- Washing Clothes - POJ 3211 01背包
- cocos2dx常见的46中+22中动作详解
- COURSERA Machine Learning WEEK1&&WEEK2
- Sudoku 数独 (Dancing links)
- FPGA研发(3) FPGA和他那些小伙伴们 (二) 器件互联。
- Unicode、GB2312、GBK和GB18030中的汉字
- ZOJ 2412 Farm Irrigation
- POJ 2057 The Lost House
- 程序更改代理ip(成佩涛黑客)
- MIT牛人解说数学体系
- ghost 安装在bae
- Linux正则表达式的初探