파게로그

[백준 2239번] 스도쿠 본문

콤퓨타 왕왕기초/PS

[백준 2239번] 스도쿠

파게 2021. 11. 29. 02:17

문제 링크: 2239번 스도쿠

https://www.acmicpc.net/problem/2239

 

empty는 채워지지 않은 칸의 인덱스들을 저장하고 있고, fill은 empty의 emptyId번째 칸을 채우는 함수이다. 즉, emptyId == empty.size()라는 조건은 empty의 모든 칸들을 다 채웠다는 것을 의미하므로, 그 때 스도쿠 퍼즐을 출력하면 된다.

 

51번째 라인의 존재 의의는 무엇일까?

 

'지금의 상태'가 '불가능한 상태'인 것에는 두 가지 경우가 있다.

첫째는, candis의 크기가 0인 것이다.

둘째는, fill()내의 for문을 다 돈 경우이다.

두 번째 경우를 고려해서, 이 때에는 값을 초기화해놓고 전 상태로 돌아가야 한다.

 

그렇지 않으면, emptyId가 자신보다 큰 empty의 영향을 받아 (원래는 자기 뒤의 empty는 채우지 않았다고 가정해야 함) candis가 잘못 구해질 수 있다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Pos {
    int row;
    int col;

    Pos(int row, int col) {
        this.row = row;
        this.col = col;
    }
}

public class Main {
    static int[][] board = new int[9][9];
    static List<Pos> empty = new ArrayList<>();

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        for (int i = 0; i < 9; i++) {
            String line = br.readLine();
            for (int j = 0; j < 9; j++) {
                board[i][j] = line.charAt(j) - '0';
                if (board[i][j] == 0) {
                    empty.add(new Pos(i, j));
                }
            }
        }

        fill(0);
    }

    static void fill(int emptyId) {
        if (emptyId == empty.size()) {
            print();
            System.exit(0);
        }

        Pos cur = empty.get(emptyId);
        List<Integer> candis = candi(cur);

        for (int item : candis) {
            board[cur.row][cur.col] = item;
            fill(emptyId + 1);
        }

        board[cur.row][cur.col] = 0;
    }

    static void print() {
        StringBuilder answer = new StringBuilder();
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                answer.append(board[i][j]);
            }
            answer.append('\n');
        }
        System.out.print(answer);
    }

    static List<Integer> candi(Pos p) {
        boolean[] possible = new boolean[10]; Arrays.fill(possible, true);

        // horizontal
        for (int i = 0; i < 9; i++) {
            possible[board[p.row][i]] = false;
        }

        // vertical
        for (int i = 0; i < 9; i++) {
            possible[board[i][p.col]] = false;
        }

        // square
        int r = (p.row / 3) * 3;
        int c = (p.col / 3) * 3;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                possible[board[r+i][c+j]] = false;
            }
        }

        List<Integer> candi = new ArrayList<>();
        for (int i = 1; i <= 9; i++) {
            if (possible[i]) {
                candi.add(i);
            }
        }
        return candi;
    }
}
Comments