1. 程式人生 > 實用技巧 >b_lc_解數獨(巧妙處理3×3方格)

b_lc_解數獨(巧妙處理3×3方格)

Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:

  • Each of the digits 1-9 must occur exactly once in each row.
  • Each of the digits 1-9 must occur exactly once in each column.
  • Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.

Empty cells are indicated by the character '.'.

方法一:回溯

這裡處理3×3方格得很巧妙,對 x/3,y/3 後會使3×3方格中任何一格的座標變為相同,這樣就方便用狀態記錄陣列記錄;
注:這裡的行和列的狀態要分開記錄

const int N=10;
class Solution {
public:
    int n, m, st_r[N][10], st_c[N][10], st_box[N][N][10];
    bool dfs(int x, int y, vector<vector<char>>& g) {
        if (y==m) return dfs(x+1, 0, g);
        if (x==n) return true;
        if (g[x][y]=='.') {
            for (char c='1'; c<='9'; c++) {
                int num=c-'0';
                if (!st_r[x][num] && !st_c[y][num] && !st_box[x/3][y/3][num]) {
                    g[x][y]=c;
                    st_r[x][num]=st_c[y][num]=st_box[x/3][y/3][num]=1;
                    if (dfs(x,y+1,g)) return true;
                    st_r[x][num]=st_c[y][num]=st_box[x/3][y/3][num]=0;
                    g[x][y]='.';
                }
            }
            return false;
        } else {
            return dfs(x,y+1,g);
        }
    }
    void solveSudoku(vector<vector<char>>& g) {
        n=g.size(), m=g[0].size();
        for (int i=0; i<n; i++)
        for (int j=0; j<m; j++) {
            if (g[i][j]!='.') {
                int num=g[i][j]-'0';
                st_r[i][num]=st_c[j][num]=st_box[i/3][j/3][num]=true;
            }
        }
        dfs(0,0,g);
    }
};