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 '.'.

方法一:回溯

py暴力解法

class Solution:
    def solveSudoku(self , g ):
        def chk_row(x,y,c):
            for i in range(9):
                if g[x][i]==c: return False
            return True
        def chk_col(x,y,c):
            for i in range(9):
                if g[i][y]==c: return False
            return True
        def chk_area(x,y,c):
            sx,sy=x//3*3,y//3*3 #将(x,y)定位到所属小九宫格的左上角位置
            for i in range(3):
                for j in range(3):
                    if g[sx+i][sy+j]==c:
                        return False
            return True
        def dfs(s,g):
            if s==ALL: 
                return True
            x,y=s//n,s%m
            if g[x][y]!='.':
                if dfs(s+1,g): return True
                return False
            else:
                for i in range(1,10):
                    nc=str(i)
                    if chk_row(x,y,nc) and chk_col(x,y,nc) and chk_area(x,y,nc):
                        g[x][y]=nc
                        if dfs(s+1,g): return True
                        g[x][y]='.'
                return False
        n,m,ALL=len(g),len(g[0]),81
        dfs(0,g)

这里处理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);
    }
};
posted @ 2020-09-15 21:43  童年の波鞋  阅读(375)  评论(0编辑  收藏  举报