leetcode-36-有效数独,leetcode-37-求解9*9数独

#include <iostream>
#include <vector>
#include <utility>
#include <unordered_map>

using namespace std;


    unordered_map<int, int> originNumber;
    void setOrigin(vector<vector <char>>& board)
    {
        for (int i = 0; i <= 8; i++) {
            for (int j = 0; j <= 8; j++) {
                cout << i << ", " << j << " ";
                if (board[i][j] != '.') {
                    originNumber[i*9+j] = 1;
                    cout << originNumber[i*9+j] << endl;
                }
                else{
                    cout << originNumber[i*9+j] << endl;
                    originNumber[i*9+j] = 0;
                }
            }     
        }
    }

    bool isOriginNumber(int row, int col)
    {
        return originNumber[row * 9 + col];
    }

    bool unique_in_row(vector<vector<char>>& board, int row, int col, char key)
    {
        for (int i = 0; i <= 8; i++) {
            if (board[row][i] == key && i != col) {//存在同行不同列的相同元素
                cout << key << "is not unique in row " << row << endl;
                return false;
            }
        }
        cout << key << "is unique in row " << row << endl; 
        return true;
    }

    bool unique_in_col(vector<vector<char>>& board, int row, int col, char key)
    {
        for (int i = 0; i <= 8; i++) {
            if (board[i][col] == key && i != row) {//存在同列不同行的相同元素
                cout << key << "is not unique in col " << col << endl;
                return false;
            }
        }
        cout << key << "is unique in col " << col << endl;
        return true;
    }

    bool unique_in_square(vector<vector<char>>& board, int row, int col, char key)
    {
        //cout << "unique_in_square: ";
        //cout << "row = " << row << " " << "col = " << col << endl; 
        int square_row = row % 3;
        int square_col = col % 3;
        //cout << "square_row = " << square_row << " " << "square_col = " << square_col << endl; 
        int startRow = row, startCol = col;

        if (square_row == 1) 
            startRow = row - 1;
        else if (square_row == 2) 
            startRow = row - 2;
        if (square_col == 1)
            startCol = col - 1;
        else if (square_col == 2)
            startCol = col - 2;
        //cout << "startRow = " << startRow << " " << "startCol = " << startCol << endl;
        for (int i = 0; i <= 2; i++) {
            for (int j = 0; j <= 2; j++) {//存在同九宫格不同行列的相同元素
                if (board[startRow+i][startCol+j] == key && startRow+i != row && startCol+j != col) {
                    cout << key << "is not unique in square " << endl;
                    return false;
                }
            }
        }
        cout << key << "is unique in square " << endl;
        return true;
    }

    int helper(vector<vector<char>>& board, int row, int col)
    {   
        if (row == 9) {
            return row;
        } else {
                bool flag;
                int nextrow = -1;   //下一个空白处的行号
                int nextcol = -1;   //下一个空白处的列号
                int j;         //计算下一个空白处的辅助数据,标志是有有下一个空白的标记位
                int depth = row;    //已经递归到的深度
                //更新到下一个位置,j == (board.size() * board[0].size())说明没有下一个空白处
                for (j = row*9+col+1; j < (board.size() * board[0].size()); j++) {
                    if (originNumber[j] == 0) {
                        nextrow = j / 9;
                        nextcol = j % 9;
                        break;
                    }
                }  
                //如果有下一个空位,则newrow,nextcol设置为下一个空位的坐标
                //如果没有下一个空位,nextrow==9表示没有下一个空白位  
                if (j == (board.size() * board[0].size())) {
                    nextrow = 9;
                    nextcol = 0;
                }

                cout << "row = " << row << " col = " << col << endl;
                cout << "nextrow = " << nextrow << " nextcol = " << nextcol << endl;

                for (int i = 1; i <= 9; i++) {
                    flag = true;
                    cout << "Try to put " << i << " in row" << row << ", col" << col << endl;
                    if (!unique_in_row(board, row, col, i+'0'))
                        flag = false;
                    if (!unique_in_col(board, row, col, i+'0'))
                        flag = false;
                    if (!unique_in_square(board, row, col, i+'0'))
                        flag = false;
                    if (flag) {
                        cout << "Put " << i << " in row" << row << ", col" << col << endl;
                        board[row][col] = i+'0';
                        //两种情况合二为一:
                        //有下一个空白处,向下递归到nextrow, nextcol处
                        //没有下一个空白处 等价于 已经正确填写最后一个空白处 等价于 找到数独的解,向下递归的nextrow == 9,直接返回9
                        depth = helper(board, nextrow, nextcol);
                        //根据depth的值
                        if (depth == 9) {
                            return depth;
                        }
                    }
                }
                //board[row][col]中1到9都尝试了,行不通
                //恢复为'.'返回上一出空白
                cout << " 1~9 are all wrong in row" << row << ", col" << col << endl;
                cout << "set row" << row << ", col" << col << " to be ." << endl;
                board[row][col] = '.';
                return row;
        }
        
    }

    void solveSudoku(vector<vector<char>>& board) {
        int first_empty_row, first_empty_col;
        for (int i = 0; i < (board.size() * board[0].size()); i++)
            if (board[i / 9][i % 9] == '.') {
                first_empty_row = i / 9;
                first_empty_col = i % 9;
                break;
            }
        cout << first_empty_row << ", " << first_empty_col << endl;
        //helper(board, first_empty_row, first_empty_col);
        helper(board, first_empty_row, first_empty_col);
    }

    bool isValidSudoku(vector<vector<char>>& board) {
        int n = board.size();
        //cout << n << endl;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cout << i << ", " << j << endl;
                if (board[i][j] == '.')
                    continue;
                if (!unique_in_row(board, i, j, board[i][j])) {
                    cout << i << ", " << j << ", " << board[i][j];
                    return  false;
                }
                
                if (!unique_in_col(board, i, j, board[i][j])){
                    cout << i << ", " << j << ", " << board[i][j];
                    return false;
                }
                
                if (!unique_in_square(board, i, j, board[i][j])){
                    cout << i << ", " << j << ", " << board[i][j] << endl;
                    return false;
                }
                
            }
        }
        return true;
    }


    int main()
    {
        /*"5"是const string 不能初始化char
        vector<vector<char> > board1 = {
            {"5","3",".",".","7",".",".",".","."},
            {"6",".",".","1","9","5",".",".","."},
            {".","9","8",".",".",".",".","6","."},
            {"8",".",".",".","6",".",".",".","3"},
            {"4",".",".","8",".","3",".",".","1"},
            {"7",".",".",".","2",".",".",".","6"},
            {".","6",".",".",".",".","2","8","."},
            {".",".",".","4","1","9",".",".","5"},
            {".",".",".",".","8",".",".","7","9"},
        };
        */
    vector<vector<char> > board1 = {
   {'.', '8', '7', '6', '5', '4', '3', '2', '1'}, 
   {'2', '.', '.', '.', '.', '.', '.', '.', '.'},
   {'3', '.', '.', '.', '.', '.', '.', '.', '.'}, 
   {'4', '.', '.', '.', '.', '.', '.', '.', '.'},
   {'5', '.', '.', '.', '.', '.', '.', '.', '.'}, 
   {'6', '.', '.', '.', '.', '.', '.', '.', '.'}, 
   {'7', '.', '.', '.', '.', '.', '.', '.', '.'}, 
   {'8', '.', '.', '.', '.', '.', '.', '.', '.'}, 
   {'9', '.', '.', '.', '.', '.', '.', '.', '.'}};

   vector<vector<char> > board = {
            {'5','3','.', '.','7','.', '.', '.', '.'},
            {'6','.', '.','1','9','5','.', '.','.'},
            {'.','9','8','.', '.','.', '.','6','.'},
            {'8','.', '.','.','6','.', '.','.','3'},
            {'4','.', '.','8','.','3','.', '.','1'},
            {'7','.', '.','.','2','.', '.','.','6'},
            {'.','6','.', '.','.', '.','2','8','.'},
            {'.', '.','.','4','1','9','.', '.','5'},
            {'.', '.','.', '.','8','.', '.','7','9'},
        };
    setOrigin(board);
    solveSudoku(board);
    
    //bool real = isValidSudoku(board);
    //cout << real << endl;
        for (int i = 0; i <= 8; i++) {
            for (int j = 0; j <= 8; j++) {
                if (j == 0)
                    cout << "\n";
                cout << board[i][j];
            }
        }   
        cout << "\n";
        return 0;
    }

 

posted @ 2021-11-09 14:37  corsican  阅读(96)  评论(0)    收藏  举报