分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程
/*
* 求解数独。
* 注:空白格用0表示。
*
* SolveSudoku.c - by LiveEveryDay
*/
#include <stdio.h>
int IsValidCell(int s[9][9], int row, int col, int val) {
// 判断行里是否重复
for (int i = 0; i < 9; i++) {
if (s[row][i] == val) {
return 0;
}
}
// 判断列里是否重复
for (int j = 0; j < 9; j++) {
if (s[j][col] == val) {
return 0;
}
}
// 判断每个宫格里是否重复
int startRow = (row / 3) * 3;
int startCol = (col / 3) * 3;
for (int i = startRow; i < startRow + 3; i++) {
for (int j = startCol; j < startCol + 3; j++) {
if (s[i][j] == val) {
return 0;
}
}
}
return 1;
}
int Backtrack(int s[9][9]) {
for (int i = 0; i < 9; i++) { // 遍历行
for (int j = 0; j < 9; j++) { // 遍历列
if (s[i][j] != 0) {
continue;
}
for (int k = 1; k <= 9; k++) { // s[i][j]这个位置放k是否合适
if (IsValidCell(s, i, j, k)) {
s[i][j] = k; // 放置k
if (Backtrack(s)) {
return 1; // 如果找到一组有效的解,立即返回。
}
s[i][j] = 0; // 回溯:撤销k,再换不同的k进行循环。
}
}
return 0; // 9个数都试完了,都不行,那么就返回无解。
}
}
return 1; // 遍历完都没有返回无解,说明找到了一组有效的解。
}
int Solve(int s[9][9]) {
return Backtrack(s);
}
void Print(int s[9][9]) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
printf("%d ", s[i][j]);
}
printf("\n");
}
}
int main(void) {
int s[9][9] = {{3, 4, 0, 0, 0, 2, 0, 1, 7},
{0, 0, 2, 9, 0, 1, 4, 0, 5},
{7, 0, 9, 0, 0, 5, 0, 0, 0},
{0, 0, 7, 6, 2, 3, 1, 5, 4},
{0, 3, 1, 0, 8, 0, 2, 7, 0},
{2, 5, 4, 1, 9, 7, 3, 0, 0},
{0, 0, 0, 2, 0, 0, 5, 0, 3},
{1, 0, 3, 7, 0, 6, 8, 0, 0},
{5, 2, 0, 3, 0, 0, 0, 6, 1}};
int r = Solve(s);
printf("Does this sudoku have a solution? %s\n", r ? "Yes" : "No");
if (r) {
printf("The solution is:\n");
Print(s);
}
return 0;
}
// Output:
/*
Does this sudoku have a solution? Yes
The solution is:
3 4 5 8 6 2 9 1 7
8 6 2 9 7 1 4 3 5
7 1 9 4 3 5 6 2 8
9 8 7 6 2 3 1 5 4
6 3 1 5 8 4 2 7 9
2 5 4 1 9 7 3 8 6
4 7 6 2 1 8 5 9 3
1 9 3 7 5 6 8 4 2
5 2 8 3 4 9 7 6 1
*/