|
|
@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
#include<stdio.h>
|
|
|
|
|
|
|
|
void output(int a[9][9]);
|
|
|
|
|
|
|
|
void complete(int a[9][9], int m, int n);
|
|
|
|
|
|
|
|
int check(int a[9][9], int row, int col, int num);
|
|
|
|
|
|
|
|
int judge(int a[9][9], int b);
|
|
|
|
|
|
|
|
void W(int a[9][9]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//任务四:判断 数组是否满足定义 并给出完整矩阵
|
|
|
|
|
|
|
|
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} };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
W(board0);
|
|
|
|
|
|
|
|
W(board1);
|
|
|
|
|
|
|
|
W(board2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void output(int a[9][9])//定义函数,按格式打印数组
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("|");//每一行的以|开始
|
|
|
|
|
|
|
|
for (int j = 0; j < 9; j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("%d", a[i][j]);
|
|
|
|
|
|
|
|
if ((j + 1) % 3 == 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("|");//区分3*3
|
|
|
|
|
|
|
|
if (j == 8)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((i + 1) % 3 == 0 && i != 8)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("|----分割---|\n");
|
|
|
|
|
|
|
|
}//每三行就换一行
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int check(int a[9][9], int row, int col, int num)
|
|
|
|
|
|
|
|
//检查某数能否放在某位置,在补全数组的函数complete中会被调用
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 对行
|
|
|
|
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (a[row][i] == num) return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 对列
|
|
|
|
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (a[i][col] == num) return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 对块
|
|
|
|
|
|
|
|
int Row = row - row % 3;
|
|
|
|
|
|
|
|
int Col = col - col % 3;
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (int j = 0; j < 3; j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (a[i + Row][j + Col] == num) return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void complete(int a[9][9], int m, int n)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 如果到达最后一行最后一列,返回成功
|
|
|
|
|
|
|
|
if (m == 9&&n==9)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("The solution of Sudoku matrix:\n");
|
|
|
|
|
|
|
|
output(a);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 移动到下一个位置
|
|
|
|
|
|
|
|
if (n == 9)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m++;
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 如果当前位置已经有数字,移动到下一个位置
|
|
|
|
|
|
|
|
if (a[m][n] != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
complete(a, m, n + 1);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 填数
|
|
|
|
|
|
|
|
for (int i = 1; i <= 9; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (check(a, m, n, i))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
a[m][n] = i;
|
|
|
|
|
|
|
|
complete(a, m, n + 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m == 9) return;
|
|
|
|
|
|
|
|
a[m][n] = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int judge(int a[9][9], int b)//判断数独是否满足定义,并返回判断值,返还值为0意味这数独满足定义
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int c = 0;//c=0意味数独满足定义
|
|
|
|
|
|
|
|
//b=0说明不打印,只判断;b=1,则该函数会打印语句
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//判断是否每一行不出现多次
|
|
|
|
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int times[9] = { 0 };
|
|
|
|
|
|
|
|
for (int j = 0; j < 9; j++)//统计第i行每个数字的出现次数
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(a[i][j]>=1)times[a[i][j] - 1]++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < 9; j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (times[j] > 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c = 1;
|
|
|
|
|
|
|
|
if (b == 1)
|
|
|
|
|
|
|
|
{ printf("False:Invalid initial Sudoku matrix!\nThe number %d in the row %d has been used!\n", j + 1, i + 1); }
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (c) { break; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (c == 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//判断是否每一列不出现多次
|
|
|
|
|
|
|
|
for (int j = 0; j < 9; j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int times[9] = { 0 };
|
|
|
|
|
|
|
|
for (int i = 0; i < 9; i++)//统计第j列每个数字的出现次数
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (a[i][j] >= 1)times[a[i][j] - 1]++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (times[i] > 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c = 1;
|
|
|
|
|
|
|
|
if (b == 1)
|
|
|
|
|
|
|
|
{ printf("False:Invalid initial Sudoku matrix!\nThe number %d in the col %d has been used!\n", i + 1, j + 1); }
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c) { break; }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//判断每一块是否不出现多次
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (int j = 0; j < 3; j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int times[9] = { 0 };
|
|
|
|
|
|
|
|
for (int m = 3 * i; m <= 3 * i + 2; m++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (int n = 3 * j; n <= 3 * j + 2; n++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (a[m][n] >= 1)times[a[m][n] - 1]++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (times[i] > 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
c = 1;
|
|
|
|
|
|
|
|
if (b == 1)
|
|
|
|
|
|
|
|
{ printf("False:Invalid initial Sudoku matrix!\nThe number %d in the block %d has been used!\n", i + 1, i + j + 1); }
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c) { break; }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c) { break; }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void W(int a[9][9])//本代码文件最重要的函数
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("The original Sudoku matrix:\n");
|
|
|
|
|
|
|
|
output(a);
|
|
|
|
|
|
|
|
if (judge(a, 0) == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
judge(a, 1);
|
|
|
|
|
|
|
|
printf("No solution!\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("True:Valid initial Sudoku matrix!\n");
|
|
|
|
|
|
|
|
complete(a, 0, 0);//进行填充数独的操作
|
|
|
|
|
|
|
|
int judgee = 1;
|
|
|
|
|
|
|
|
for (int i = 0; i < 9; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (int j = 0; j < 9; j++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (a[i][j] == 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("No solution!\n");
|
|
|
|
|
|
|
|
judgee = 0;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (judgee == 0){break;}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|