LeetCode 37 Sudoku Solver(求解数独)(*)
来源:互联网 发布:红包自动抢软件 编辑:程序博客网 时间:2024/05/15 08:51
翻译
写一个程序来通过填充空格求解数独。空格用'.'表示。你可以假定这里只有唯一解。(示例图片看下文)
原文
代码
这道题我没写……不过为了博客的连续性,先凑一篇占个位置,以后再修改。
class Solution {public: bool col[10][10],row[10][10],f[10][10]; bool flag = false; void solveSudoku(vector<vector<char>>& board) { memset(col,false,sizeof(col)); memset(row,false,sizeof(row)); memset(f,false,sizeof(f)); for(int i = 0; i < 9;i++){ for(int j = 0; j < 9;j++){ if(board[i][j] == '.') continue; int temp = 3*(i/3)+j/3; int num = board[i][j]-'0'; col[j][num] = row[i][num] = f[temp][num] = true; } } dfs(board,0,0); } void dfs(vector<vector<char>>& board,int i,int j){ if(flag == true) return ; if(i >= 9){ flag = true; return ; } if(board[i][j] != '.'){ if(j < 8) dfs(board,i,j+1); else dfs(board,i+1,0); if(flag) return; } else{ int temp = 3*(i/3)+j/3; for(int n = 1; n <= 9; n++){ if(!col[j][n] && !row[i][n] && !f[temp][n]){ board[i][j] = n + '0'; col[j][n] = row[i][n] = f[temp][n] = true; if(j < 8) dfs(board,i,j+1); else dfs(board,i+1,0); col[j][n] = row[i][n] = f[temp][n] = false; if(flag) return; } } board[i][j] = '.'; } }};
class Solution { // Table which allows compute the value of the cell // from the unambiguous bit mask as maskToValue[(mask%11)-1] // uses the fact that (1<<i)%11 is unique for i = [0..8] and never produces 0 const char maskToValue[10] = {'1','2','9','3','5','6','8','4','7','6'}; struct SudokuSolver { // Using mask for each cell which constraints values which can be in the cell // Yeap, it is more storage, comparing to rows/cols/sqrs approach // but it allows to do super-fast reactive constraint propagation array<array<uint16_t,9>,9> board; SudokuSolver() { // Initializing the board with mask, which permits all numbers for (int i=0; i<9; i++) for (int j=0; j<9; j++) board[i][j] = 0x1ff; } // adds value v [1..9] to the board, return false if it violates constraints bool add(int i, int j, int v) { return set(i, j, 1<<(v-1)); } // set a value mask to the cell (i,j) and reactively updates constraints bool set(int i, int j, uint16_t mask) { int16_t prev = board[i][j]; if (prev == mask) return true; if (!(prev&mask)) return false; board[i][j] = mask; return propagate(i,j,mask); } // propagates constraints as a result of setting i,j to mask bool propagate(int i, int j, uint16_t mask) { for (int k=0; k<9; k++) { if (k!=j && !addConstraint(i, k, mask)) return false; if (k!=i && !addConstraint(k, j, mask)) return false; int ii = (i/3)*3 + (k/3); int jj = (j/3)*3 + (k%3); if ((i != ii || j != jj) && !addConstraint(ii, jj, mask)) return false; } return true; } // prohibits putting value in mask to the cell (i,j) bool addConstraint(int i, int j, uint16_t mask) { int16_t newMask = board[i][j] &~ mask; if (newMask != board[i][j]) { if (newMask == 0) return false; board[i][j] = newMask; if (((newMask-1)&newMask)==0) { // good news - we have only one possibility for the cell (i,j) return propagate(i, j, newMask); } } return true; } // list of cell coordinates with >1 possibilities for values vector<pair<int,int>> v; void solve() { // finding all ambiguous cells for (int i=0; i<9; i++) { for (int j=0; j<9; j++) { uint16_t mask = board[i][j]; if (mask&(mask-1)) v.push_back(make_pair(i,j)); } } // note: it is also a good idea to sort v by the hamming weight, but // without sorting it is still super-fast // running backtracking as is backtrack(0); } // backtracking bool backtrack(int k) { if (k == v.size()) return true; int i = v[k].first; int j = v[k].second; uint16_t mask = board[i][j]; if (mask&(mask-1)) { // the board state is so compact and backtracking depth is so shallow, so // it is cheaper to make a snapshot of the state vs. doing classical // undo at each move auto snapshot = board; for (uint16_t cand = 1; cand<=0x1ff; cand = cand <<1) { if (set(i, j, cand) && backtrack(k+1)) return true; board = snapshot; } return false; } else { return backtrack(k + 1); } } };public: void solveSudoku(vector<vector<char>>& board) { SudokuSolver solver; for (int i=0; i<9; i++) { for (int j=0; j<9; j++) { char c = board[i][j]; if (c != '.' && !solver.add(i,j,c-'0')) return; } } // At this point 9 of 10 sudokus published in magazines will be solved by constraint propagation // only 'hard' sudokus will require some (limited) backtracking solver.solve(); for (int i=0; i<9; i++) for (int j=0; j<9; j++) board[i][j] = maskToValue[(solver.board[i][j]%11)-1]; }};
一定要每天坚持呐……
4 1
- LeetCode 37 Sudoku Solver(求解数独)(*)
- LeetCode: Sudoku Solver (数独求解)
- 【LeetCode】37. Sudoku Solver 数独求解
- LeetCode:Valid Sudoku,Sudoku Solver(数独游戏)
- 数独求解 Sudoku Solver
- Sudoku Solver:数独求解
- [LeetCode 36&37] Valid Sudoku & Sudoku Solver (数独问题)
- Leetcode #37. Sudoku Solver 数独求解 结题报告
- Leetcode-Sudoku Solver(数独)
- Sudoku Solver 求解数独问题
- LeetCode Sudoku Solver 数独C++程序
- [LeetCode] [数独问题] Sudoku Solver
- 数独(Sudoku)求解程序
- LeetCode-37. Sudoku Solver (JAVA)(数独游戏解集)
- leetcode 37. Sudoku Solver 36. Valid Sudoku 数独问题
- LeetCode(37) Sudoku Solver
- Sudoku Solver 破解数独 @LeetCode 附DFS感想
- Sudoku Solver 破解数独@LeetCode - CSDN blog
- Smash fear, learn anything 无所畏惧,学无止境-Tim Ferriss的Ted
- Android注释规范
- Exercises 3.17 输入一段文字到string类型的vector中,并将其改为大写
- 利用php+curl调用极光IM第三方REST API方法经验
- centos6.5使用JMX时远程连接不上的问题
- LeetCode 37 Sudoku Solver(求解数独)(*)
- NSURLConnection 实现webView显示HTTPS页面
- 提示Android APP性能
- c++编程必备啊..
- iOS 9开发(适配)中需要注意的事项总结
- 成为一名更好的程序员:如何阅读源代码
- android 显示flash视频播放器
- Larry Smithr在TED演讲:为什么你干不成一番大事业
- 本地json文件的编辑器,node-webkit开发的exe程序