diff --git a/task 4.c b/task 4.c new file mode 100644 index 0000000..dbeabe9 --- /dev/null +++ b/task 4.c @@ -0,0 +1,163 @@ +#include +#include + +#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; +}