检测数独是否合格。
思路:
填充一遍就知道是否合格。
基本暴力搜索的思想。
1 /*************************************************************************************************** 2 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. 3 The Sudoku board could be partially filled, where empty cells are filled with the character ‘.‘. 4 Valid Sudoku.png 5 A partially filled sudoku which is valid. 6 Note: 7 A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated. 8 **************************************************************************************************/ 9 #include<stdio.h> 10 #include<stdbool.h> 11 12 /*检查行*/ 13 bool checkRow(char **line,int i,int length,char c){ 14 for(int j = 0;j < length;j++){ 15 if(line[i][j] == c)return false; 16 } 17 return true; 18 } 19 20 /*检查列*/ 21 bool checkColumn(char **line,int j,int length,char c){ 22 for(int i = 0;i < length;i++){ 23 if(line[i][j] == c)return false; 24 } 25 return true; 26 } 27 28 /*检查九宫格*/ 29 bool checkNCell(char **cell,int i,int j,char c){ 30 for(int m = 0;m < 3;m++){ 31 for(int n = 0;n < 3;n++) 32 if(cell[i + m][j + n] == c)return false; 33 } 34 return true; 35 } 36 37 /** 38 board 数独数组 39 i,j 当前单元格的坐标 40 boardRowSize 行的上界 41 boardColSize 列的上界 42 **/ 43 bool checkSudoku(char **board, int i, int j, int boardRowSize, int boardColSize){ 44 bool result = false;//记录结果 45 if(board[i][j] == ‘.‘){//未知数字 46 for(int k = 1;k < 10;k++){//遍历0->9 47 if(checkRow(board,i,boardColSize,k + ‘0‘) && 48 checkColumn(board,j,boardRowSize,k + ‘0‘) && 49 checkNCell(board,(i/3)*3,(j/3)*3,k + ‘0‘)){//检测是否能填充该数字 50 board[i][j] = k + ‘0‘;//填充 51 if(i == boardRowSize - 1 && j == boardColSize - 1)return true;//全部填充完毕,数独合格 52 else if(j == boardColSize - 1)result = checkSudoku(board,i + 1,0,boardRowSize,boardColSize);//第一行检测完毕,下一行从头开始 53 else result = checkSudoku(board,i,j + 1,boardRowSize,boardColSize);//检测同一行的下一格 54 if(result)break;//不符合数独 55 else board[i][j] = ‘.‘; 56 } 57 } 58 }else{//已有的数字时跳过 59 if(i == boardRowSize - 1 && j == boardColSize - 1)return true;//全部检查完毕,数独合格 60 else if(j == boardColSize - 1)result = checkSudoku(board,i + 1,0,boardRowSize,boardColSize);//一行检查完毕,下一行开始 61 else result = checkSudoku(board,i,j + 1,boardRowSize,boardColSize);//检测同一行的下一格 62 } 63 return result; 64 } 65 66 /** 67 *找出正确的解 68 */ 69 bool isValidSudoku(char** board, int boardRowSize, int boardColSize) { 70 return checkSudoku(board,0,0,boardRowSize,boardColSize); 71 } 72 73 void main(){ 74 char **board = (char **)malloc(9*sizeof(char *)); 75 for(int i = 0;i < 9;i++){ 76 board[i] = (char *)malloc(10*sizeof(char)); 77 for(int j = 0;j < 9;j++) 78 board[i][j] = ‘.‘; 79 board[i][9] = ‘\0‘; 80 } 81 board[0][1] = ‘8‘; 82 board[0][2] = ‘7‘; 83 board[0][3] = ‘6‘; 84 board[0][4] = ‘5‘; 85 board[0][5] = ‘4‘; 86 board[0][6] = ‘3‘; 87 board[0][7] = ‘2‘; 88 board[0][8] = ‘1‘; 89 board[1][0] = ‘2‘; 90 board[2][0] = ‘3‘; 91 board[3][0] = ‘4‘; 92 board[4][0] = ‘5‘; 93 board[5][0] = ‘6‘; 94 board[6][0] = ‘7‘; 95 board[7][0] = ‘8‘; 96 board[8][0] = ‘9‘; 97 98 printf("result = %d\n",isValidSudoku(board,9,9)); 99 for(int i = 0;i < 9;i++){ 100 printf("%s\t\n",board[i]); 101 free(board[i]); 102 } 103 free(board); 104 }
思路2:
题目并没有要求数独必须是能解出来的,所以没有必要这么复杂的去判断。
只需要判断给出的数字中有没有重复的。
/*************************************************************************************************** Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character ‘.‘. Valid Sudoku.png A partially filled sudoku which is valid. Note: A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated. **************************************************************************************************/ #include<stdio.h> #include<stdbool.h> /*检查出现的数字中是否有重复的*/ bool checkRow(char **line,int i,int length){ int a[10] = {0}; for(int j = 0;j < length;j++){ if(line[i][j] != ‘.‘)a[line[i][j] - ‘0‘]++; } for(int j = 0;j < 10;j++){ if(a[j] > 1)return false; } return true; } /*检查出现的数字中是否有重复的*/ bool checkColumn(char **line,int j,int length){ int a[10] = {0}; for(int i = 0;i < length;i++){ if(line[i][j] != ‘.‘)a[line[i][j] - ‘0‘]++; } for(int i = 0;i < 10;i++){ if(a[i] > 1)return false; } return true; } /*检查出现的数字中是否有重复的*/ bool checkNCell(char **cell,int i,int j){ int a[10] = {0}; for(int m = 0;m < 3;m++){ for(int n = 0;n < 3;n++){ if(cell[i + m][j + n] != ‘.‘)a[cell[i + m][j + n] - ‘0‘]++; } } for(int k = 0;k < 10;k++){ if(a[k] > 1)return false; } return true; } bool isValidSudoku(char** board, int boardRowSize, int boardColSize) { int i,j; for(i = 0;i < boardRowSize;i++){//检测行 if(!checkRow(board,i,boardColSize))return false; } for(i = 0;i < boardColSize;i++){//检测列 if(!checkColumn(board,i,boardRowSize))return false; } for(i = 0,j = 0;i < boardRowSize && j < boardColSize;j += 3){//检测列 if(!checkNCell(board,i,j))return false; if(j == boardColSize - 3){ i += 3; j = -3; } } return true; } void main(){ char **board = (char **)malloc(9*sizeof(char *)); for(int i = 0;i < 9;i++){ board[i] = (char *)malloc(10*sizeof(char)); for(int j = 0;j < 9;j++) board[i][j] = ‘.‘; board[i][9] = ‘\0‘; } board[0][2] = ‘1‘; board[0][6] = ‘3‘; board[1][2] = ‘4‘; board[1][6] = ‘1‘; board[3][4] = ‘8‘; board[4][1] = ‘1‘; board[4][4] = ‘2‘; board[5][6] = ‘6‘; board[5][7] = ‘3‘; board[6][0] = ‘7‘; board[7][0] = ‘5‘; board[7][1] = ‘8‘; board[7][6] = ‘4‘; board[8][1] = ‘5‘; board[8][4] = ‘4‘; board[8][8] = ‘8‘; printf("result = %d\n",isValidSudoku(board,9,9)); for(int i = 0;i < 9;i++){ printf("%s\t\n",board[i]); free(board[i]); } free(board); }
时间: 2024-12-22 13:17:50