diff --git a/sudoku4.c b/sudoku4.c new file mode 100644 index 0000000..35624a1 --- /dev/null +++ b/sudoku4.c @@ -0,0 +1,178 @@ +/*-------------------*/ +/*实验:数独矩阵------*/ +/*4. 对一个不完整的“数独矩阵”进行判断,如果满足“数独矩阵”则补充完整,*/ +/*使之成为一个完整的“数独矩阵”:*/ +/*-------------------*/ +#include +#include +#include +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); +}