You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
4.3 KiB

#include <stdio.h>
#include <stdbool.h>
#define SIZE 9
// 打印数独矩阵
void printSudoku(int board[SIZE][SIZE]) {
int row,col;
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
printf("%d ", board[row][col]);
}
printf("\n");
}
}
// 检查当前位置是否安全
bool isSafe(int board[SIZE][SIZE], int row, int col, int num) {
// 检查行
int x;
for (x = 0; x < SIZE; x++) {
if (board[row][x] == num) {
return false;
}
}
// 检查列
for (x = 0; x < SIZE; x++) {
if (board[x][col] == num) {
return false;
}
}
// 检查 3x3 子网格
int startRow = row - row % 3;
int startCol = col - col % 3;
int i,j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (board[i + startRow][j + startCol] == num) {
return false;
}
}
}
return true;
}
// 解决数独的回溯算法
bool solveSudoku(int board[SIZE][SIZE]) {
// 遍历整个数独矩阵
int row,col;
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++) {
// 如果当前位置是空的
if (board[row][col] == 0) {
// 尝试填充 1 到 9
int num;
for (num = 1; num <= 9; num++) {
if (isSafe(board, row, col, num)) {
// 放置数字
board[row][col] = num;
// 递归调用解决数独
if (solveSudoku(board)) {
return true;
}
// 如果失败,回溯
board[row][col] = 0;
}
}
// 如果 1 到 9 都不能放置,返回 false
return false;
}
}
}
// 如果所有位置都填充完毕,返回 true
return true;
}
// 检查数独矩阵的有效性
bool isValidSudoku(int board[SIZE][SIZE]) {
// 检查行和列是否有重复的数字
int row,col;
for (row = 0; row < SIZE; row++) {
int rowSet[10] = {0};
int colSet[10] = {0};
for (col = 0; col < SIZE; col++) {
int num = board[row][col];
if (num != 0) {
if (rowSet[num]) {
printf("Row %d has duplicate number %d\n", row, num);
return false;
}
rowSet[num] = 1;
if (colSet[num]) {
printf("Column %d has duplicate number %d\n", col, num);
return false;
}
colSet[num] = 1;
}
}
}
// 检查 3x3 子网格是否有重复的数字
int block;
for (block = 0; block < 9; block++) {
int blockSet[10] = {0};
int startRow = block / 3 * 3;
int startCol = block % 3 * 3;
int i,j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
int num = board[startRow + i][startCol + j];
if (num != 0) {
if (blockSet[num]) {
printf("3x3 block starting at (%d, %d) has duplicate number %d\n", startRow, startCol, num);
return false;
}
blockSet[num] = 1;
}
}
}
}
return true;
}
int main() {
int board[SIZE][SIZE] = {
{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}
};
printf("The original Sudoku matrix:\n");
printSudoku(board);
if (isValidSudoku(board)) {
printf("True:Valid initial Sudoku matrix!\n");
if (solveSudoku(board)) {
printf("The solution of Sudoku matrix:\n");
printSudoku(board);
} else {
printf("No solution!\n");
}
} else {
printf("False:Invalid initial Sudoku matrix!\n");
printf("No solution!\n");
}
return 0;
}