문제 출처: https://www.acmicpc.net/problem/2239
문제

위 그림은 참 잘도 스도쿠 퍼즐을 푼 경우이다. 각 행에 1부터 9까지의 숫자가 중복 없이 나오고, 각 열에 1부터 9까지의 숫자가 중복 없이 나오고, 각 3×3짜리 사각형(9개이며, 위에서 색깔로 표시되었다)에 1부터 9까지의 숫자가 중복 없이 나오기 때문이다.
하다 만 스도쿠 퍼즐이 주어졌을 때, 마저 끝내는 프로그램을 작성하시오.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
    private static List<int[]> target;
    private static StringBuilder sb;
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int[][] sudoku = new int[9][9];
        target = new ArrayList<>();
        for (int i = 0; i < 9; i++) {
            char[] temp = reader.readLine().toCharArray();
            for (int j = 0; j < 9; j++) {
                sudoku[i][j] = temp[j] - '0';
                if (sudoku[i][j] == 0) target.add(new int[] { i, j });
            }
        }
       dfs(sudoku, 0);
        System.out.println(sb);
    }
    private static void dfs(int[][] sudoku, int idx) {
        if (sb != null) return;
        if (idx == target.size()) {
            sb = new StringBuilder();
            for (int i = 0; i < 9; i++) {
                for (int j = 0; j < 9; j++) {
                    sb.append(sudoku[i][j]);
                }
                sb.append("\n");
            }
            return;
        }
        int y = target.get(idx)[0];
        int x = target.get(idx)[1];
        boolean[] temp = new boolean[10];
        checkCross(sudoku, temp, y, x);
        checkInner(sudoku, temp, y / 3 * 3, x / 3 * 3);
        for (int k = 1; k < 10; k++) {
            if (!temp[k]) {
                sudoku[y][x] = k;
                dfs(sudoku, idx + 1);
                sudoku[y][x] = 0;
            }
        }
    }
    // 가로, 세로 체크
    private static void checkCross(int[][] sudoku, boolean[] temp, int r, int c) {
        for (int i = 0; i < 9; i++) {
            if (sudoku[r][i] != 0) temp[sudoku[r][i]] = true;
            if (sudoku[i][c] != 0) temp[sudoku[i][c]] = true;
        }
    }
    // 내부 3x3 사각형 체크
    private static void checkInner(int[][] sudoku, boolean[] temp, int r, int c) {
        for (int i = r; i < r + 3; i++) {
            for (int j = c; j < c + 3; j++) {
                if (sudoku[i][j] != 0) temp[sudoku[i][j]] = true;
            }
        }
    }
}
