C语言判断数独是否多解
0. 数独
数独(shù dú)是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复
1. 想法
只有一个解的数独才是合法的, 于是我想写个程序判断一下
2. 思路
感觉就是把所有数独的解求出来, 要是有两个, 就是有多个解~
3. 代码实现
#include <stdio.h>
/* 这是一个用于实验的数独
int L[9][9] = {
{0,5,2,0,0,4,0,0,0,},
{7,0,0,9,0,0,8,0,1,},
{0,9,0,0,2,0,0,0,6,},
{1,8,0,0,5,0,0,0,0,},
{0,0,0,0,4,0,9,0,7,},
{0,0,0,2,0,8,0,0,0,},
{0,0,0,5,0,0,1,4,0,},
{5,0,0,0,9,0,6,0,0,},
{9,4,0,0,0,1,0,0,2,},
};
*/
int L[9][9];
void bp (){ //输出数独的函数
int i,j;
for(i=0;i<9;i++){
for(j=0;j<9;j++)
printf("%d ", L[i][j]);
printf("\n");
}
printf("\n");
}
int n_is1to9[10] = {0,0,0,0,0,0,0,0,0,0};
void is1to9 (int * L){
int i;
for(i=0;i<9;i++) n_is1to9[L[i]]++;
}
int sum=0;
void foo (int fi,int fj){
int i,j,e,a,b;
int arr[9];
int min_num = 10, min_i = 0, min_j = 0, target_num=0;
int min_arr[10]={0,0,0,0,0,0,0,0,0,0};
//得到每一格的可能情况个数
for(i=0;i<9;i++)
for(j=0;j<9;j++)
if (!L[i][j]){
for(e=0;e<10;e++) n_is1to9[e]=0;
a = i/3; b = j/3;
arr[0] = L[a*3][b*3]; arr[1] = L[a*3][b*3+1]; arr[2] = L[a*3][b*3+2];
arr[3] = L[a*3+1][b*3]; arr[4] = L[a*3+1][b*3+1]; arr[5] = L[a*3+1][b*3+2];
arr[6] = L[a*3+2][b*3]; arr[7] = L[a*3+2][b*3+1]; arr[8] = L[a*3+2][b*3+2];
is1to9(arr);
is1to9(L[i]);
for(e=0;e<9;e++) arr[e] = L[e][j];
is1to9(arr);
target_num = 0;
for(e=1;e<10;e++) if(!n_is1to9[e]) target_num++;
if (!target_num){
L[fi][fj]=0;
return;//某步出错返回
}
if (target_num < min_num){
min_num = target_num;
min_i = i;
min_j = j;
for(e=1;e<10;e++) min_arr[e] = n_is1to9[e];
}
}
//数字填完, 输出结果
if(min_num==10){
bp();
sum++;
L[fi][fj] = 0;
return;
}
//从可能情况最少的开始枚举
for(i=1;i<10;i++)
if(!min_arr[i]){
L[min_i][min_j] = i;
foo(min_i, min_j);
}
L[fi][fj] = 0;//说明前面某数字出错,返回
return;
}
int main (){
//输入数独
printf("输入9*9个数字, 数字之间不用分隔, 空的数字用0表示:\n");
int i,j;
char s[9];
for(i=0;i<9;i++){
scanf("%s", s);
for(j=0;j<9;j++){
L[i][j] = s[j] - 48;
}
}
printf("数独的解分别为:\n");
foo(0,0);
printf("共%d个解,", sum);
if(sum == 1) printf("符合要求\n");
else printf("不符合要求\n");
return 0;
}
4. 写完后的一些想法
花两个小时写出来的程序, 介于个人水平比较菜, 感觉很多地方都可以优化,而且执行的时候会出现[1] ???? abort
的提示但不影响结果, 我自己搞明白后再补充吧
输出结果显示