题目地址: https://leetcode.com/problems/sudoku-solver/
// 将字符串的数独题转换成 int[9][9] void setBoard(int board[9][9], char ** b, int boardRowSize, int boardColSize){ for (int row = 0; row < boardRowSize; ++row) for (int col = 0; col < boardColSize; ++col){ if (b[row][col] == ‘.‘) board[row][col] = 0; else board[row][col] = b[row][col] - ‘0‘; } } // 计算位置{row,col}的候选个数,并在cands返回候选列表 int calcCandNum(int board[9][9], int row, int col, int * cands){ if (board[row][col] != 0) return 0;// 已知位置 int cand[9] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };// // 筛除 非法的数字 // 按行筛除 for (int i = 0; i < 9; ++i){ if (board[row][i] != 0) cand[board[row][i] - 1] = 0; } // 按列 for (int i = 0; i < 9; ++i){ if (board[i][col] != 0) cand[board[i][col] - 1] = 0; } // 按block // 计算左上角坐标 int r0, c0; r0 = (row / 3) * 3; c0 = (col / 3) * 3; for (int i = r0; i < r0 + 3; ++i) for (int j = c0; j < c0 + 3; ++j){ if (board[i][j] != 0) cand[board[i][j] - 1] = 0; } // 剩下的1 的总和便是 候选个数 int sum = 0; for (int i = 0; i < 9; ++i){ if (cand[i]){ cands[sum] = i + 1; sum++; } } return sum; } typedef struct tagCandidate{ int row, col; // 位置 int n; // 候选个数 int cands[9]; // 候选列表 int solved; // 数独是否已经解开 }Candidate; // 从数独板中返回候选个数最少的位置,其候选信息存入 cand void getCandidate(int board[9][9], Candidate* cand){ int candList[9]; int currN; cand->n = 10; cand->solved = 1; for (int row = 0; row < 9; ++row) for (int col = 0; col < 9; ++col){ if (board[row][col] != 0){ // 该位置有值了 continue; } // 说明数独还有空洞 cand->solved = 0; // 计算该孔洞的候选个数,及候选序列 currN = calcCandNum(board, row, col,candList); if (currN < cand->n){ cand->n = currN; cand->row = row; cand->col = col; for (int i = 0; i < currN; ++i) cand->cands[i] = candList[i]; } } } int solveBoard(int board[9][9]){ Candidate cand; getCandidate(board, &cand); if (cand.solved){ return 1; } for (int i = 0; i < cand.n; ++i){ // guess[cand.row][cand.col] = recursiveFlag; // flag we guess 好像这个没什么用 board[cand.row][cand.col] = cand.cands[i]; // fill what we guess if (solveBoard(board)) // we‘d solved it return 1; else{ // we‘d not solved it // clear what we guess // clearGuess(int board[9][9], int guess[]) board[cand.row][cand.col] = 0; } } // 到这里来!! 不可能 , 无解???? return 0; } // 将结果写回字符数组 b 中 void outputBoard(char **b, int board[9][9]){ for(int row = 0; row < 9; ++row) for(int col = 0; col < 9; ++col){ b[row][col] = ‘0‘ + (board[row][col]); } } void solveSudoku(char** b, int boardRowSize, int boardColSize) { int board[9][9]; setBoard(board, b, boardRowSize, boardColSize); solveBoard(board); outputBoard(b,board); }
时间: 2024-10-15 12:43:16