您的位置:首页 > 其它

数独(nyoj 722)

2014-02-12 13:27 183 查看

数独

时间限制:1000 ms | 内存限制:65535 KB

难度:4
描述
数独是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个3*3宫内的数字均含1-9,不重复。 每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。

有一天hrdv碰到了一道号称是世界上最难的数独的题目,作为一名合格的程序员,哪能随随便便向困难低头,于是他决定编个程序来解决它。。



输入第一行有一个数n(0< n <100),表示有n组测试数据,每组测试数据是由一个9*9的九宫格构成,0表示对应的格子为空输出输出一个9*9的九宫格,为这个数独的答案样例输入
1
0 0 5 3 0 0 0 0 0
8 0 0 0 0 0 0 2 0
0 7 0 0 1 0 5 0 0
4 0 0 0 0 5 3 0 0
0 1 0 0 7 0 0 0 6
0 0 3 2 0 0 0 8 0
0 6 0 5 0 0 0 0 9
0 0 4 0 0 0 0 3 0
0 0 0 0 0 9 7 0 0

样例输出
1 4 5 3 2 7 6 9 8
8 3 9 6 5 4 1 2 7
6 7 2 9 1 8 5 4 3
4 9 6 1 8 5 3 7 2
2 1 8 4 7 3 9 5 6
7 5 3 2 9 6 4 8 1
3 6 7 5 4 2 8 1 9
9 8 4 7 6 1 2 3 5
5 2 1 8 3 9 7 6 4


/*
注意输出最终结果的时候,是在dfs函数中,
因为最后都会回溯到原来的值,
在main函数输出的话结果与最初值是相等的
之前就错在这了= =
*/
#include <stdio.h>

int map[9][9];
bool flag = 0;

int f(int a, int b, int x)
{//判断map[a][b]是否能填写数字x
int i, j;
for(i = 0; i < 9; i++)
{
if(map[a][i] == x)
return 0;
}
for(i = 0; i < 9; i++)
{
if(map[i][b] == x)
return 0;
}
int n, m;
m = a / 3 * 3;
n = b / 3 * 3;
for(i = m; i < m + 3; i++)
{
for(j = n; j < n + 3; j++)
{
if(map[i][j] == x)
return 0;
}
}
return 1;
}

void dfs(int a, int b)
{
int i, j;
if(flag == 0)
{
if(a == 9 && b == 0)
{
flag = 1;
for(i = 0; i < 9; i ++)
{
for(j = 0; j < 9; j++)
printf("%d ", map[i][j]);
printf("\n");
}
return ;
}
if(b == 9)
{//此行填满,填写下一行
dfs(a + 1, 0);
}
if(map[a][b] != 0)
{
dfs(a, b + 1);
}
else
{
for(i = 1; i < 10; i++)
{//1到9,这9个数字挨个试
if(f(a, b, i) == 1)
{
map[a][b] = i;
dfs(a, b + 1);
map[a][b] = 0;
}
}
}
}
}

int main (void)
{
int i, j, n;
scanf("%d", &n);
while(n--)
{
for(i = 0; i < 9; i ++)
{
for(j = 0; j < 9; j++)
scanf("%d", &map[i][j]);
}
//printf("\n");
dfs(0, 0);

flag = 0;
}
return 0;
}

/*
6 9 7 8 3 0 0 0 0
4 0 0 0 0 0 0 0 0
3 0 1 4 5 0 0 0 0
8 0 9 0 0 0 0 0 0
2 0 5 0 1 0 9 0 8
0 0 0 0 0 0 5 0 4
0 0 0 0 2 4 1 0 9
0 0 0 0 0 0 0 0 3
0 0 0 0 0 1 6 8 7
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: