我用了《编程之美》1.15节的第二种方法,也就是用矩阵行交换和列交换,这个方法的优点就是速度很快,缺点就是只能构造9!种,离所有合法数独总数差的很远。
自我感觉我实现的还不错,构造9*9的数独,我只用了3*3的基本九宫格和3*3的变换数组,省了7/9的空间。
关于书上提到的第一种用DFS的方法,我觉得用来求解数独倒不错,我打算有空写个求解数独的程序。
CODE
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
const int transform[3][3] = {{1,2,0}, {0,1,2}, {2,0,1}};
int GenerateGrid(int* grid);
int GetCell(int (*grid)[3], int x, int y);
int Show(int (*grid)[3]);
int main(int argc, char *argv[])
{
int grid[3][3];
GenerateGrid(grid[0]);
Show(grid);
system("pause");
return 0;
}
//随机生成3*3的九宫格
int GenerateGrid(int* grid)
{
int index = 0;
int sum = 36; //0~8之和
memset(grid, 0, sizeof(int) * 9);
srand((unsigned)time(0));
for(int i = 0; i < 8; ++i)
{
index = rand() % 9;
while(grid[index] != 0)
{
index = rand() % 9;
}
grid[index] = i + 1;
sum -= index;
}
grid[sum] = 9;
}
//通过行列变换数组,实际只用3*3的数组,而不是9*9的
int GetCell(int (*grid)[3], int x, int y)
{
if(x < 0 || x > 8 || y < 0 || y > 8)
return -1;
return grid[transform[y/3][x%3]][transform[x/3][y%3]];
}
//输出已完成的数独
int Show(int (*grid)[3])
{
for(int i = 0; i < 9; ++i)
{
for(int j = 0; j < 9; ++j)
{
printf("%2d",GetCell(grid, i, j));
}
puts(""); //换行
}
}