[LeetCode .37] Sudoku Solver

Problem

비어있는 스도쿠 배열에서 스도쿠 룰에 맞게 채워넣어라

Solution

우선, 간단히 스도쿠 룰에 대해 설명하자면

스도쿠 문제의 솔루션은 백트래킹 방법이 가장 보편화되어있다. 추가적인 탐색 방법으로는 전체 비어있는 곳을 탐색하며, 위 3가지 룰에 위반되지 않는 숫자를 넣고 다음 탐색을 시도한다.

빠른 속도와 간결성을 위해 아래 팁을 사용

Code

class Solution {
public:
    bool vert[10][10];
    bool hori[10][10];
    bool area[4][4][10];
    int xdp[82];
    int ydp[82];

    bool checkIn(int x, int y, int value){
        // 스도쿠 배열의 각 행,열,지역 체크
        if(vert[y][value]) return false;
        if(hori[x][value]) return false;
        if(area[y/3][x/3][value]) return false;
        
        // 체크인
        vert[y][value] = true;
        hori[x][value] = true;
        area[y/3][x/3][value] = true;
        return true;
        
    }
    void checkOut(int x, int y, int value){
        // 체크아웃
        vert[y][value] = false;
        hori[x][value] = false;
        area[y/3][x/3][value] = false;
    }
    
    bool back(vector<vector<char>>& board, int p){
        
        // 스도쿠 끝에 도달하면 back 완전 종료
        if(p == 81)
            return true;
        
        int x = xdp[p];
        int y = ydp[p];
        
        // 이미 숫자가 존재 한다면 다음번호로 탐색
        if(board[y][x] != '.') {
            if(back(board, p+1)) return true;
            return false;
        }
        

        for(int i = 1; i <10; i++){
            // 이미 check in 된 숫자라면 무시
            if(!checkIn(x, y, i)) continue;
            board[y][x] = i + '0';

            if( back(board, p+1) ) return true;

            // 원상복귀
            board[y][x] = '.';
            checkOut(x, y, i);
        }
        return false;
    }
    
    // Main Start
    void solveSudoku(vector<vector<char>>& board) {
        // 이미 채워진 부분은 check in
        for(int i = 0; i <9; i++)
            for(int j = 0 ;j <9; j++){
                if(board[i][j]=='.') continue;
                checkIn(j, i, board[i][j]-'0');
            }

        // 각 포인트별 좌표에 대한 테이블 생성
        for(int i = 0 ;i < 81; i++){
            xdp[i] = i%9;
            ydp[i] = i/9;
        }
        back(board, 0);
    }
};

Reference

https://leetcode.com/problems/sudoku-solver/