You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
4.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*-------------------*/
/*实验:数独矩阵------*/
/*4. 对一个不完整的“数独矩阵”进行判断,如果满足“数独矩阵”则补充完整,*/
/*使之成为一个完整的“数独矩阵”:*/
/*-------------------*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void randseedInit(){
srand(time(NULL));
}
void printBoad(int _board[9][9]){
int i,j;
for ( i = 0; i < 9;i++){
if(!(i%3))printf("|-----------------------|\n");
for ( j = 0; j < 9;j++){
if(!(j%3))
printf("| ");
if(_board[i][j]==0)
printf(". ");
else
printf("%d ", _board[i][j]);
}
printf("|\n");
}
printf("|-----------------------|\n");
}
void makeNSeq(int _seq[],int n){//产生1-n的不重复序列传入一个数组名指针
int ct[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int i;
for (i = 0; i < n; i++) {
int t = rand() % n;
while(ct[t=rand() % n]);
ct[t]++;
_seq[i] = t+1;
}
}
void initBoard(int _board[9][9]){
int i,j;
for ( i = 0; i < 9;i++)
for ( j = 0; j < 9;j++)
_board[i][j] = 0;
}
void makeRandomBoard(int _board[9][9]){
initBoard(_board);
int i_1,i,idx;
for ( i_1 = 0; i_1 < 3;i_1++){
int seq[9];
makeNSeq(seq, 9);
for ( i = 0; i < 3;i++){
int where[9];
makeNSeq(where, 9);
for ( idx = 0; idx < 3;idx++){
_board[i_1 * 3 + i][where[idx+i*3]-1] = seq[idx+i*3];
}
}
}
}
void printWhyInvalid(int num,int is_col,int index,int *valid,int ndpt){
if(*valid){
if(ndpt)printf("False:Invalid initial Sudoku matrix!\n The number %d in the %s %d has been used!\n", num, (is_col ? "col" : "block"), index);
*valid = 0;
};
}
int whoBeUsedInSeq(int seq[9]){
int ct[10]={0,0,0,0,0,0,0,0,0,0};
int i;
for ( i = 0; i < 9;i++){
ct[seq[i]]++;
}
for (i = 1; i < 10;i++){
if(ct[i]>1)
return i;
}
return 0;
}
void matrixT(int _board[9][9],int _output[9][9]){
int i,j;
for (i = 0; i < 9;i++)
for ( j = 0; j < 9;j++)
_output[j][i] = _board[i][j];
}
void resortByBlock(int _board[9][9], int _output[9][9]) {
int i,j;
for ( i = 0; i < 9;i++){
int p1x = i / 3;
int p1y = i % 3;
for (j = 0; j < 9; j++){
int p2x = j / 3;
int p2y = j % 3;
_output[i][j] = _board[p1x * 3 + p2x][p1y * 3 + p2y];
}
}
}
int judgeValid(int _board[9][9],int ndpt){
int valid = 1;
int boardT[9][9];
int boardB[9][9];
matrixT(_board, boardT);
resortByBlock(_board, boardB);
int i;
for ( i = 0; i < 9;i++){
int who = whoBeUsedInSeq(boardT[i]);
if(who)
printWhyInvalid(who, 1, i+1, &valid,ndpt);
who = whoBeUsedInSeq(boardB[i]);
if(who)
printWhyInvalid(who, 0, i+1, &valid,ndpt);
who = whoBeUsedInSeq(_board[i]);
if(who)
valid = 0;
}
return valid;
}
int try(int _b[9][9],int where[]){
int w = where[0];
if(!judgeValid(_b,0))
return 0;
if(w==-1){
printf("The Solution of Sudoku Matrix:\n");
printBoad(_b);
return 1;
}
int n,i,j;
for ( n = 1; n <= 9;n++){
int _bt[9][9];
for ( i = 0; i < 9;i++)
for ( j = 0; j < 9;j++)
_bt[i][j] = _b[i][j];
_bt[w / 9][w % 9] = n;
if(try(_bt, &where[1])){
return 1;
}
}
return 0;
}
int solve(int _board[9][9]){
int idx = 0;
int where[81];
int _b[9][9];
int i,j;
for ( i = 0; i < 9;i++)
for ( j = 0; j < 9;j++)
_b[i][j] = _board[i][j];
for ( i = 0; i < 81;i++)
where[i] = -3;
int pos = 0;
while (pos < 81) {
if (!_b[pos / 9][pos % 9]){
where[idx]=pos;
idx++;
}
pos++;
}
where[idx] = -1;
if(try(_b, where)){
return 1;
}
else{
printf("No Solution!\n");
return 0;
};
}
int main(){
randseedInit();
int board[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}};
printBoad(board);
solve(board);
}