【深搜】数独(math.cpp)

Description

Input

输入一共 15 行,包含一个新数独的实例。第奇数行包含左右方向的符号( < > ),第偶数行包含上下方向的符号( ^ v )。

Output

输出包含 9 行,每行 9 1~9 的数字,以单个空格隔开。输入保证解惟一。

Sample Input

< >   > <   > <

v v ^ ^ v v ^ ^ ^

 < <   > <   > <

^ ^ ^ v ^ ^ ^ v v

 < <   < <   > >

 > <   > >   > >

v ^ ^ ^ ^ v v v ^

 > >   > >   < >

v v ^ v ^ v ^ v ^

 > <   < >   > >

 < <   < <   > <

v ^ v v v v ^ ^ v

 < >   > <   < >

^ v v v ^ v ^ v v

 < >   < >   < >

Sample Output

4 9 1 7 3 6 5 2 8

2 3 7 8 1 5 6 4 9

5 6 8 2 4 9 7 3 1

9 1 3 6 5 4 8 7 2

8 5 4 9 7 2 1 6 3

7 2 6 3 8 1 9 5 4

3 4 9 5 6 8 2 1 7

1 8 5 4 2 7 3 9 6

6 7 2 1 9 3 4 8 5
Code:
#if 0
<>><><
vv^^vv^^^
<<><><
^^^v^^^vv
<<<<>>
><>>>>
v^^^^vvv^
>>>><>
vv^v^v^v^
><<>>>
<<<<><
v^vvvv^^v
<>><<>
^vvv^v^vv
<><><>
#endif

#include <iostream>

#define SIZE 10

using namespace std;

int num[SIZE][SIZE] =
{
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
	0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
	0, 1, 1, 1, 2, 2, 2, 3, 3, 3,
	0, 4, 4, 4, 5, 5, 5, 6, 6, 6,
	0, 4, 4, 4, 5, 5, 5, 6, 6, 6,
	0, 4, 4, 4, 5, 5, 5, 6, 6, 6,
	0, 7, 7, 7, 8, 8, 8, 9, 9, 9,
	0, 7, 7, 7, 8, 8, 8, 9, 9, 9,
	0, 7, 7, 7, 8, 8, 8, 9, 9, 9,
};

bool row_visited[SIZE][SIZE], col_visited[SIZE][SIZE], block_visited[SIZE][SIZE], flag;
int row_comp[SIZE][SIZE], col_comp[SIZE][SIZE], a[SIZE][SIZE];

int comp(int x, int y)
{
	return (x > y) ? 1 : -1;
}

bool check(int x, int y, int k) // 能放吗?
{
	if ((row_visited[x][k]) || (col_visited[y][k]) || (block_visited[num[x][y]][k])) // 哎呀,不符合数独的基本原则,不成
	{
		return false;
	}
	if ((row_comp[x][y]) && (row_comp[x][y] != comp(k, a[x][y-1]))) // 哎呀,行比较不对,不成
	{
		return false;
	}
	if ((col_comp[x][y]) && (col_comp[x][y] != comp(k, a[x-1][y]))) // 列比较不对,不成
	{
		return false;
	}
	row_visited[x][k] = col_visited[y][k] = block_visited[num[x][y]][k] = true; // 可以就保存结果
	
	return true; // 可以啦!
}

void print(void) // 输出
{
	int i, j;
	
	for (i = 1; i <= 9; i++)
	{
		for (j = 1; j <= 9; j++)
		{
			printf("%d ", a[i][j]); // 非小视野会PE,别的OJ改一下就行了
		}
		printf("\n");
	}
	
	return;
}

void dfs(int x, int y) // 深搜过程
{
	int i;
	
	if (flag) // 之前已经填完啦,题目说只输出一个,溜了溜了
	{
		return;
	}
	if (x == 10) // 全部填完
	{
		print(); // 输出结果
		flag = true;
		return; // 溜了溜了
	}
	for (i = 1; i <= 9; i++)
	{
		if (check(x, y, i))
		{
			a[x][y] = i;
			if (y == 9) // 搜索下一个
			{
				dfs(x + 1, 1);
			}
			else
			{
				dfs(x, y + 1);
			}
			a[x][y] = 0; // 回溯
			row_visited[x][i] = col_visited[y][i] = block_visited[num[x][y]][i] = false;
		}
	}
}

int main(int argc, char** argv)
{
	int i, j;
	char c;
	
	for (i = 1; i <= 9; i++) // 最麻烦的输入
	{
		for (j = 1; j <= 9; j++)
		{
			if (j % 3)
			{
				cin >> c;
				if (c == '>') // 保存行比较
				{
					row_comp[i][j+1] = -1;
				}
				else
				{
					row_comp[i][j+1] = 1;
				}
			}
		}
		if (i % 3)
		{
			for (j = 1; j <= 9; j++)
			{
				cin >> c;
				if (c == '^') // 保存列比较
				{
					col_comp[i+1][j] = 1;
				}
				else
				{
					col_comp[i+1][j] = -1;
				}
			}
		}
	}
	
	dfs(1, 1); // 开始深搜
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/drtlstf/article/details/80717895