0 数独是什么
https://gitee.com/umecjf/cmput201/blob/master/lab12/lab12.pdf
解一个9X9的数独,有的数独有唯一解,有的数独有几万个解。
还有9个小九宫格
1 知识
涉及系统调用,文件操作等。还有递归的算法。
3 代码
本代码实现的功能,主要在ex12q21.c中,实现了解数独并输出的功能,在ex12q2.c中是调用的方式,大家按照需要修改api即可。其中的参数k,是为了限制输出的解法。
代码
#include <stdio.h>
#include "lab12.h"
void Sudoku(int a[9][9],int n);
int result=0;
int k = 0;
int sudoku(int a[9][9], int num)
{
k = num;
Sudoku(a,0);
if(result==0) {
return 0;
}
return result;
}
int get_weight(int x) {
int sum = 0;
while (x != 0) {
sum++;
x /= 10;
}
return sum;
}
void print(int a[9][9])
{
result++;
if (result > k) {
return ;
}
char file_name[255] = {'\0'};
sprintf(file_name, "sol%0*d.txt", get_weight(k) - get_weight(result) + 1, result);
FILE * fp = fopen(file_name, "w");
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
fprintf(fp, "%d ",a[i][j]);
}
fprintf(fp, "\n");
}
fclose(fp);
}
// 对于a这个数独,i,j位置放一个数字,k是否可行。
int check(int a[9][9],int i,int j,int k)
{
int m,n;
// 第判断行内无重复的0-9
for(n=0;n<9;n++)
{
if(a[i][n] == k)
return 0;
}
// 判断列内无重复的0-9
for(m=0;m<9;m++)
{
if(a[m][j] == k)
return 0;
}
// 判断所在的小九宫格内无重复的0-9
int t1=(i/3)*3,t2=(j/3)*3;
for(m=t1;m<t1+3;m++)
{
for(n=t2;n<t2+3;n++)
{
if(a[m][n] == k)
return 0;
}
}
return 1;
}
// 递归调用函数,判断第n个数,该填什么。n取 0 - 80, 9 X 9 = 81
void Sudoku(int a[9][9],int n)
{
int temp[9][9];
int i,j;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
temp[i][j]=a[i][j];
}
i=n/9; j=n%9;
if(a[i][j] != 0) // 如果不是0,则不需要填,直接找下一个
{
if(n == 80)
print(temp);
else
Sudoku(temp,n+1);
}
else // 如果是0,则需要填,
{
for(int k=1;k<=9;k++)
{
int flag=check(temp,i,j,k);
if(flag) // 如果可以填k这个数子,就在这个基础上填。
{
temp[i][j]=k;
if(n == 80)
print(temp);
else
Sudoku(temp,n+1);
temp[i][j]=0; // 恢复为0,继续填下一个可能的值。
}
}
}
}