#include <iostream> #include <vector> #include <string> using namespace std; // 108 ms class Solution0 { public: struct Trace { int i; int j; int s; Trace() : i(0), j(0), s(0) {} Trace(int _i, int _j, int _s) : i(_i), j(_j), s(_s) {} }; void solveSudoku(vector<vector<char>>& board) { vector<vector<bool>> rowFlag(9, vector<bool>(9, false)); vector<vector<bool>> colFlag(9, vector<bool>(9, false)); vector<vector<bool>> boxFlag(9, vector<bool>(9, false)); vector<vector<bool>> occupied(9, vector<bool>(9, false)); int i, j; int remains = 0; for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { if (board[i][j] != '.') { int k = board[i][j] - '1'; rowFlag[i][k] = true; colFlag[j][k] = true; boxFlag[(i / 3) * 3 + j / 3][k] = true; occupied[i][j] = true; } else { remains++; } } } bool found = false; vector<Trace> ans(remains); placeNumber(board, found, ans, 0, remains, occupied, rowFlag, colFlag, boxFlag); } void placeNumber(vector<vector<char>>& board, bool &found, vector<Trace> &ans, int count, int remains, vector<vector<bool>> &occupied, vector<vector<bool>> &rowFlag, vector<vector<bool>> &colFlag, vector<vector<bool>> &boxFlag) { // suppose we have only one solution, if we found one, no need to continue if (found) return; int i, j; // found one solution! copy answers to the board if (count == remains) { found = true; int k = 0; for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { if (board[i][j] == '.') { board[i][j] = ans[k++].s + '1'; } } } return; } for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { if (occupied[i][j] == false) { for (int s = 0; s < 9; s++) { // try to place a number ans[count] = Trace(i, j, s); // if it's valid, set flag and place another number if (!rowFlag[i][s] && !colFlag[j][s] && !boxFlag[(i / 3) * 3 + j / 3][s]) { rowFlag[i][s] = true; colFlag[j][s] = true; boxFlag[(i / 3) * 3 + j / 3][s] = true; occupied[i][j] = true; placeNumber(board, found, ans, count + 1, remains, occupied, rowFlag, colFlag, boxFlag); } } // can't find a right number, backtrack // set back the flag to false // be aware to set the previous number, not the current if (count <= 0) return; Trace t = ans[count - 1]; rowFlag[t.i][t.s] = false; colFlag[t.j][t.s] = false; boxFlag[(t.i / 3) * 3 + t.j / 3][t.s] = false; occupied[t.i][t.j] = false; return; } } } } }; // 36 ms class Solution { public: void solveSudoku(vector<vector<char>>& board) { vector<vector<bool>> rowFlag(10, vector<bool>(10, false)); vector<vector<bool>> colFlag(10, vector<bool>(10, false)); vector<vector<bool>> boxFlag(10, vector<bool>(10, false)); int i, j; for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { if (board[i][j] != '.') { int k = board[i][j] - '1'; rowFlag[i][k] = true; colFlag[j][k] = true; boxFlag[(i / 3) * 3 + j / 3][k] = true; } } } bool found = false; placeNumber(board, found, 0, rowFlag, colFlag, boxFlag); } bool placeNumber(vector<vector<char>>& board, bool &found, int depth, vector<vector<bool>> &rowFlag, vector<vector<bool>> &colFlag, vector<vector<bool>> &boxFlag) { // suppose we have only one solution, if we found one, no need to continue if (found) return true; // found one solution! copy answers to the board if (depth == 81) { found = true; return true; } int i, j; i = depth / 9; j = depth % 9; if (board[i][j] != '.') { return placeNumber(board, found, depth + 1, rowFlag, colFlag, boxFlag); } else { for (int s = 0; s < 9; s++) { // if it's valid, set flag and place another number if (!rowFlag[i][s] && !colFlag[j][s] && !boxFlag[(i / 3) * 3 + j / 3][s]) { // try to place a number board[i][j] = s + '1'; rowFlag[i][s] = true; colFlag[j][s] = true; boxFlag[(i / 3) * 3 + j / 3][s] = true; if (placeNumber(board, found, depth + 1, rowFlag, colFlag, boxFlag)) return true; // backtrack rowFlag[i][s] = false; colFlag[j][s] = false; boxFlag[(i / 3) * 3 + j / 3][s] = false; board[i][j] = '.'; } } return false; } } }; int main() { vector<string> board0 = { "..9748...", "7........", ".2.1.9...", "..7...24.", ".64.1.59.", ".98...3..", "...8.3.2.", "........6", "...2759.." }; vector<string> board1 = { "53..7....", "6..195...", ".98....6.", "8...6...3", "4..8.3..1", "7...2...6", ".6....28.", "...419..5", "....8..79" }; vector<vector<char> > board(9, vector<char>(9, 0)); int i, j; // board0 for (i = 0; i < board0.size(); i++) { for (j = 0; j < board0[i].length(); j++) { board[i][j] = board0[i][j]; } } Solution s; s.solveSudoku(board); for (i = 0; i < board.size(); i++) { for (j = 0; j < board[i].size(); j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("-----------------\n"); // board1 for (i = 0; i < board1.size(); i++) { for (j = 0; j < board1[i].length(); j++) { board[i][j] = board1[i][j]; } } s.solveSudoku(board); for (i = 0; i < board.size(); i++) { for (j = 0; j < board[i].size(); j++) { printf("%c ", board[i][j]); } printf("\n"); } return 0; }