您的位置:首页 > 其它

ZOJ-2580

2014-03-20 21:32 246 查看
数独求解,以前做的时候曾想过用程序能不能计算出来,那时候除了枚举不会任何算法。。现在用回溯挺简单,注意每步搜的时候用可填数字最小的点,一步一步搜,碰到无解的情况就回溯掉,深搜函数写的有点烂,感觉前面的判断条件太多了,还要多加练习

#include<stdio.h>
#include<string.h>

static int find = 0;

int possible_choose(int s[9][9], int p[9], int row, int col)
{
int i, j, total = 9;
for (i = 0; i < 9; i++)
if (s[i][col] && p[s[i][col] - 1])
{
p[s[i][col] - 1] = 0;
total--;
}

for (j = 0; j < 9; j++)
if (s[row][j] && p[s[row][j] - 1])
{
p[s[row][j] - 1] = 0;
total--;
}

int bi = row / 3 * 3, bj = col / 3 * 3;
for (i = bi; i < bi + 3; i++)
for (j = bj; j < bj + 3; j++)
if (s[i][j] && p[s[i][j] - 1])
{
p[s[i][j] - 1] = 0;
total--;
}
return total;
}

void copy_array(int from[9], int to[9])
{
int i, index = 0;
memset(to, 0, 9 * sizeof(int));
for (i = 0; i < 9; i++)
if (from[i])
to[index++] = from[i];
}

int next_position(int s[9][9], int r[9])
{
int i, j, min = 10, position = 100;
for (i = 0; i < 9; i++)
for (j = 0; j < 9; j++)
if (s[i][j] == 0)
{
int p[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int total = possible_choose(s, p, i, j);
if (total < min)
{
if (!total)
return -1;
else
{
min = total;
copy_array(p, r);
position = i * 10 + j;
}
}
}
return position;
}

void print_sudoku(int s[9][9])
{
int i, j;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
printf("%d", s[i][j]);
putchar('\n');
}
}

void sudoku(int s[9][9])
{
if (find)
return;

int r[9], next = next_position(s, r);
if (next == 100)
{
find = 1;
print_sudoku(s);
return;
}
if (next == -1)
return;
int i, x = next / 10, y = next % 10;
for (i = 0; i < 9 && r[i]; i++)
{
s[x][y] = r[i];
sudoku(s);
s[x][y] = 0;
}
}

int main()
{
int n, i, j, s[9][9];
scanf("%d", &n);
getchar();
while (n--)
{
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
s[i][j] = getchar() - '0';
getchar();
}
find = 0;
sudoku(s);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: