#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int x; //存放数组的横坐标
int y; //存入数组的纵坐标
} ElemType;
static ElemType list[81]; //定义一个表空间
int len = -1; //len记录表的大小
void AddListElem (ElemType);
int GetListElem (ElemType *, int);
void ShowMe (int [][9]);
int AddCount (int [][9]);
int CheckLine (int [][9], int, int);
int CheckRow (int [][9], int, int);
int CheckPalace (int [][9], int, int, int);
int GetListElem (ElemType *e, int i)
{//取得元素
if (i < 0)
{
return 0;
}
*e = list[i];
return 1;
}
void AddListElem (ElemType e)
{//把数独原本为空的坐标存入表中
len++;
list[len] = e;
}
int CheckPalace (int arr[][9], int line, int row, int count)
{//检查小宫
int i, j;
int a, b;
i = line / 3 * 3;
j = row / 3 * 3; //i,j为一个小宫的起始横纵下标
for (a = i; a < i + 3; ++a)
{
for (b = j; b < j + 3; ++b)
{
if (arr[a][b] == count)
{
return 1;
}
}
}
return 0;
}
int CheckRow (int arr[][9], int row, int count)
{//检查列
int i;
for (i = 0; i < 9; ++i)
{
if (arr[i][row] == count)
{
return 1;
}
}
return 0;
}
int CheckLine (int arr[][9], int line, int count)
{//检查行
int j;
for (j = 0; j < 9; ++j)
{
if (arr[line][j] == count)
{
return 1;
}
}
return 0;
}
int AddCount (int arr[][9])
{//添加数
int i, j, k;
int count;
ElemType e;
k = -1;
for (i = 0; i < 9; ++i)
{
for (j = 0; j < 9; )
{
count = 1;
if (!arr[i][j])
{
k++;
while ( ( CheckLine (arr, i, count) || CheckRow (arr, j, count)
|| CheckPalace (arr, i, j, count) ) && count <= 9 )
{
count ++;
}
if (count > 9)
{
do
{
arr[i][j] = 0;
if ( GetListElem (&e, k - 1) )
{
k--;
i = e.x;
j = e.y;
}
else
{
return 0;
}
count = arr[i][j] + 1;
while ( ( CheckLine (arr, i, count) || CheckRow (arr, j, count)
|| CheckPalace (arr, i, j, count) ) && count <= 9 )
{
count++;
}
}while (count > 9);
arr[i][j] = count;
}
else
{
arr[i][j] = count;
j++;
}
}
else
{
j++;
}
}
}
return 1;
}
void ShowMe (int arr[][9])
{//显示数独
int i, j;
for (i = 0; i < 9; ++i)
{
if ( (i+1) % 3 == 1 )
{
printf (" ------------------------/n");
}
for (j = 0; j < 9; ++j)
{
if ( (j + 1) % 3 == 1 )
{
printf ("%2c", '|');
}
printf ("%2d", arr[i][j]);
}
printf ("%2c/n", '|');
}
printf (" ------------------------/n");
}
int main (int argc, char *argv[])
{
FILE *out;
char ch;
int i, j, k;
ElemType e;
int arr[9][9];
memset ( arr, 0, 81 * sizeof (int) );
if ( argc == 2 && !strcmp ("/?", argv[1]) || argc == 1 )
{
printf ("求出数独的解/n/n");
printf ("SUDOKU 数据 路径/n/n");
return 0;
}
if (argc == 3 || argc == 2)
{
k = 0;
for (i = 0; i < 9; ++i)
{
for (j = 0; j < 9; ++j)
{
ch = argv[1][k];
arr[i][j] = atoi (&ch);
//sscanf (&argv[1][k], "%d", &arr[i][j]);
k++;
if ( !arr[i][j] )
{
e.x = i;
e.y = j;
AddListElem (e);
}
}
}
if ( AddCount (arr) )
{
//ShowMe (arr);
}
else
{
printf ("该数独无解/n");
return -1;
}
if (argc == 3)
{
out = fopen (argv[2], "at");
if (out)
{
for (i = 0; i < 9; ++i)
{
for (j = 0; j < 9; ++j)
{
fprintf (out, "%2d", arr[i][j]);
}
fprintf (out, "/n");
}
fprintf (out, "/n");
fclose (out);
}
return 0;
}
ShowMe (arr);
}
else
{
printf ("使用格式有误/n");
return 1;
}
return 0;
}