POJ3074----Sudoku

Sudoku

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8575   Accepted: 3074

Description

In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,

. 2 7 3 8 . . 1 .
. 1 . . . 6 7 3 5
. . . . . . . 2 9
3 . 5 6 9 2 . 8 .
. . . . . . . . .
. 6 . 1 7 4 5 . 3
6 4 . . . . . . .
9 5 1 8 . . . 7 .
. 8 . . 6 5 3 4 .

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

527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936

Source

Stanford Local 2006

把数独问题转成精确覆盖,课设要做这个就来学了下dlx

/*************************************************************************
    > File Name: sudoku.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年01月06日 星期二 14时46分52秒
 ************************************************************************/

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int n = 350;
const int m = 800;
const int inf = 0x3f3f3f3f;
const int N = 1000 * 1000;
bool mat[1000][1000];
char su[100];
int cnt[m];
int most;
bool ans[N];
int head;

struct Node
{
	int up, down, left, right;
	int col, row;
}node[N];

void init (int m)
{
	memset (ans, 0, sizeof(ans));
	for (int i = 0; i <= m; ++i)
	{
		node[i].left = i - 1;
		node[i].right = i + 1;
		node[i].col = i;
		node[i].up = i;
		node[i].down = i;
		cnt[i] = 0;
	}
	node[0].left = m;
	node[m].right = 0;
}

void remove(int c)
{
	node[node[c].left].right = node[c].right;
	node[node[c].right].left = node[c].left;
	for (int i = node[c].down; i != c; i = node[i].down)
	{
		for (int j = node[i].right; j != i; j = node[j].right)
		{
			--cnt[node[j].col];
			node[node[j].up].down = node[j].down;
			node[node[j].down].up = node[j].up;
		}
	}
}

void resume(int c)
{
	node[node[c].left].right = c;
	node[node[c].right].left = c;
	for (int i = node[c].up; i != c; i = node[i].up)
	{
		for (int j = node[i].left; j != i; j = node[j].left)
		{
			++cnt[node[j].col];
			node[node[j].down].up = j;
			node[node[j].up].down = j;
		}
	}
}

bool Dacing_Link_X()
{
	if (node[324].right == 324)
	{
		return true;
	}
	int mins = inf;
	int c;
	for (int i = node[324].right; i != 324; i = node[i].right)
	{
		if (cnt[i] < mins)
		{
			mins = cnt[i];
			c = i;
		}
	}
	remove(c);
	for (int i = node[c].down; i != c; i = node[i].down)
	{
		for (int j = node[i].right; j != i; j = node[j].right)
		{
			remove(node[j].col);
		}
		ans[node[i].row] = 1;
		if (Dacing_Link_X())
		{
			return true;
		}
		for (int j = node[i].left; j != i; j = node[j].left)
		{
			resume(node[j].col);
		}
		ans[node[i].row] = 0;
	}
	resume(c);
	return false;
}

int in_grid(int i, int j)
{
	++i;
	++j;
	if (1 <= i && i <= 3 && 1 <= j && j <= 3)
	{
		return 1;
	}
	if (1 <= i && i <= 3 && 4 <= j && j <= 6)
	{
		return 2;
	}
	if (1 <= i && i <= 3 && 7 <= j && j <= 9)
	{
		return 3;
	}
	if (4 <= i && i <= 6 && 1 <= j && j <= 3)
	{
		return 4;
	}
	if (4 <= i && i <= 6 && 4 <=j && j <= 6)
	{
		return 5;
	}
	if (4 <= i && i <= 6 && 7 <= j && j <= 9)
	{
		return 6;
	}
	if (7 <= i && i <= 9 && 1 <= j && j <= 3)
	{
		return 7;
	}
	if (7 <= i && i <= 9 && 4 <= j && j <= 6)
	{
		return 8;
	}
	if (7 <= i && i <= 9 && 7 <= j && j <= 9)
	{
		return 9;
	}
}

void add(int i, int j, int k)
{
	int x = (i * 9 + j) * 9 + k;
	mat[x][i * 9 + j] = 1;
	mat[x][81 + i * 9 + k] = 1;
	mat[x][162 + j * 9 + k] = 1;
	int g = in_grid(i, j);
	mat[x][243 + (g - 1) * 9 + k] = 1;
}

int main()
{
//	printf("please enter your sudoku\n");
//
	while (~scanf("%s", su))
	{
		if (!strcmp(su, "end"))
		{
			break;
		}
		most = 1000;
		memset (mat, 0, sizeof(mat));
		init(324);
		int cur = 325;
		for (int i = 0; i < 9; ++i)
		{
			for (int j = 0; j < 9; ++j)
			{
				if (su[i * 9 + j] == '.')
				{
					for (int k = 0; k < 9; ++k)
					{
						add(i, j, k);
					}
				}
				else
				{
					int k = su[i * 9 + j] - '1';
					add(i, j, k);
				}
			}
		}
		for (int i = 0; i < 729; ++i)
		{
			int s = cur;
			int pre = cur;
			for (int j = 0; j < 324; ++j)
			{
				if (!mat[i][j])
				{
					continue;
				}
				int pos = j;
				node[cur].up = node[pos].up;
				node[node[pos].up].down = cur;
				node[cur].down = pos;
				node[pos].up = cur;
				node[cur].row = i;
				node[cur].col = pos;
				node[cur].left = pre;
				node[pre].right = cur;
				node[cur].right = s;
				cnt[pos]++;
				node[s].left = cur;
				pre = cur;
				cur++;
			}
		}
		Dacing_Link_X();
		for (int i = 0; i < 81; ++i)
		{
			for (int j = 0; j < 9; ++j)
			{
				if (ans[i * 9 + j])
				{
					printf("%d", j + 1);
					break;
				}
			}
		}
		printf("\n");
	}
	return 0;
}
时间: 2024-10-11 08:37:12

POJ3074----Sudoku的相关文章

POJ3074 Sudoku(lowbit优化搜索)

In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . . . 6 7 3 5 . . . . . . . 2 9 3 . 5 6 9 2 . 8 . . . . . . . . . . . 6 . 1 7 3 5 . 3 6 4 . . . . . . . 9 5 1 8 . . . 7 .

Dancing Links 专题总结

算法详细:Dancing Links博客 1.精确覆盖: ZOJ3209 Treasure Map HUST1017 Exact cover POJ3074 Sudoku 2.可重复覆盖: HDU2295 Radar FZU1686 神龙的难题

【POJ3074】Sudoku DLX(Dancing Links)

数独就要DLX,不然不乐意. 数独的DLX构造:9*9个点每一个点有9种选择,这构成了DLX的729行,每行.列.阵有限制,均为9行(/列/阵),然后每行(/列/阵)都有九种数的情况.于是就有了3*9*9列.可是由于一个位置仅仅能选一个,所以又有9*9列,每列连接一个点的九种选数情况. 终于有4*9*9=324列,9*9*9=729行. 处理: 有些点已经有数了,可是这并不重要,我们仅仅须要给这个点加上一个行,为它已经选的数.而不要把9种情况都加上,这样在有精确覆盖的情况下(即有解),第四部分的

LeetCode37 Sudoku Solver

题目: Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by the character '.'. You may assume that there will be only one unique solution. A sudoku puzzle... ...and its solution numbers marked in red.  (Hard)

*Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by the character '.'. You may assume that there will be only one unique solution. A sudoku puzzle... ...and its solution numbers marked in red. public clas

Valid Sudoku

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character '.'. A partially filled sudoku which is valid. Note:A valid Sudoku board (partially

[LeetCode]Valid Sudoku

检测数独是否合格. 思路: 填充一遍就知道是否合格. 基本暴力搜索的思想. 1 /*************************************************************************************************** 2 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. 3 The Sudoku board could be parti

POJ Sudoku 数独填数 DFS

题目链接:Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18105   Accepted: 8772   Special Judge Description Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Fig

Valid Sudoku leetcode

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character '.'. A partially filled sudoku which is valid. 判断九宫格的合理性(并不一定有解),只需要依次判断行.列.9个子九宫格是否

LeetCode OJ:Valid Sudoku(有效数独问题)

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character '.'. 注意这里的有效数独并非指的是可以解出来,只要存在的数满足数独的条件就可以了. 原理很简单,但是判定在同一个blocks的时候出了点问题,没想到判定方法,看了下