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.

184 lines
4.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <stdio.h>
void print(int board[9][9]){
printf("|-----------------------|\n");
int i,j;
for(i=0;i<9;i++){
printf("| ");
for(j=0;j<9;j++){
if(board[i][j]==0) printf(". ");
else printf("%d ",board[i][j]);
if(j%3==2) printf("| ");
}
printf("\n");
if(i%3==2){
printf("|-----------------------|\n");
}
}
}
void check(int board[9][9]){
printf("The original Sudoku matrix:\n");
print(board);
int i,j,k;
//判断每一行数字是否重复
for(i=0;i<9;i++){
int cnt[10]={}; //统计每个数字出现次数
for(j=0;j<9;j++){
cnt[board[i][j]]++;
}
for(j=1;j<=9;j++){
if(cnt[j]>1){
printf("False:Invalid initial Sudoku matrix!\n");
printf("The number %d in the col %d has been used!\n",j,i+1);
return;
}
}
}
//判断每一列数字是否重复
for(i=0;i<9;i++){
int cnt[10]={}; //统计每个数字出现次数
for(j=0;j<9;j++){
cnt[board[j][i]]++;
}
for(j=1;j<=9;j++){
if(cnt[j]>1){
printf("False:Invalid initial Sudoku matrix!\n");
printf("The number %d in the row %d has been used!\n",j,i+1);
return;
}
}
}
//判断每个九宫格数字是否重复
for(k=0;k<9;k++){
int cnt[10]={}; //统计每个数字出现次数
//起始行为k/3*3
for(i=k/3*3;i<k/3*3+3;i++){
//起始列为k%3*3
for(j=k%3*3;j<k%3*3+3;j++){
cnt[board[i][j]]++;
}
}
for(j=1;j<=9;j++){
if(cnt[j]>1){
printf("False:Invalid initial Sudoku matrix!\n");
printf("The number %d in the block %d has been used!\n",j,k+1);
return;
}
}
}
printf("True:Valid initial Sudoku matrix!\n");
return;
}
//定义check_plus函数判断是否为数独矩阵
int check_plus(int board[9][9]){
int i,j,k;
for(i=0;i<9;i++){
int cnt[10]={};
for(j=0;j<9;j++){
cnt[board[i][j]]++;
}
for(j=1;j<=9;j++){
if(cnt[j]>1){
return 0;
}
}
}
for(i=0;i<9;i++){
int cnt[10]={};
for(j=0;j<9;j++){
cnt[board[j][i]]++;
}
for(j=1;j<=9;j++){
if(cnt[j]>1){
return 0;
}
}
}
for(k=0;k<9;k++){
int cnt[10]={};
for(i=k/3*3;i<k/3*3+3;i++){
for(j=k%3*3;j<k%3*3+3;j++){
cnt[board[i][j]]++;
}
}
for(j=1;j<=9;j++){
if(cnt[j]>1){
return 0;
}
}
}
return 1;
}
int solve(int board[9][9]){
int i,j;
for(i=0;i<9;i++){
for(j=0;j<9;j++){
if(board[i][j]==0){ //找到待填的位置
int num; //遍历填写1~9
for(num=1;num<=9;num++){
board[i][j]=num;
//若可以填,则继续递归求解新数独
if(check_plus(board)){
if(solve(board)){
return 1; //成功填写,找到一组解
}
}
board[i][j]=0; //无解,继续尝试下一个数
}
return 0; //若不管填几都无法满足,说明无解
}
}
}
}
void final_step(board){
check(board);
if(solve(board)){
printf("The solution of Sudoku matrix:\n");
print(board);
}
else printf("No solution\n");
}
int main(){
int board0[9][9] = {{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}};
int board1[9][9] = {{8, 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}};
int board2[9][9] = {{5, 2, 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}};
final_step(board0);
final_step(board1);
final_step(board2);
return 0;
}