메모리: 19840 KB, 시간: 352 ms
백트래킹, 구현
2025년 1월 3일 22:08:35
스도쿠는 매우 간단한 숫자 퍼즐이다. 9×9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3×3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다음을 보자.

위 그림은 참 잘도 스도쿠 퍼즐을 푼 경우이다. 각 행에 1부터 9까지의 숫자가 중복 없이 나오고, 각 열에 1부터 9까지의 숫자가 중복 없이 나오고, 각 3×3짜리 사각형(9개이며, 위에서 색깔로 표시되었다)에 1부터 9까지의 숫자가 중복 없이 나오기 때문이다.
하다 만 스도쿠 퍼즐이 주어졌을 때, 마저 끝내는 프로그램을 작성하시오.
9개의 줄에 9개의 숫자로 보드가 입력된다. 아직 숫자가 채워지지 않은 칸에는 0이 주어진다.
9개의 줄에 9개의 숫자로 답을 출력한다. 답이 여러 개 있다면 그 중 사전식으로 앞서는 것을 출력한다. 즉, 81자리의 수가 제일 작은 경우를 출력한다.
/**
* Author: yngbao97, Yuk Yejin
* Problem: 스도쿠_2239
* Date: 2025.01.03
*/
import java.util.*;
import java.lang.*;
import java.io.*;
public class Main {
static BufferedReader br;
static BufferedWriter bw;
static StringTokenizer st;
static int[][] sudoku;
static int[][] test;
static int[] row;
static int[] col;
static int[][] grid;
static boolean complete;
public static void main(String[] args) throws Exception {
br = new BufferedReader(new InputStreamReader(System.in));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
sudoku = new int[9][9];
test = new int[9][9];
grid = new int[3][3];
row = new int[9];
col = new int[9];
for (int i = 0; i < 9; i++) {
char[] input = br.readLine().toCharArray();
for (int j = 0; j < 9; j++) {
sudoku[i][j] = input[j] - '0';
test[i][j] = sudoku[i][j];
row[i] |= 1 << sudoku[i][j];
col[j] |= 1 << sudoku[i][j];
grid[i / 3][j / 3] |= 1<< sudoku[i][j];
}
}
complete = false;
dfs(0, 0);
StringBuilder 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");
}
bw.write(sb.toString());
bw.flush();
bw.close();
br.close();
}
private static void dfs(int r, int c) throws IOException {
if (complete) return;
if (r >= 9) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
sudoku[i][j] = test[i][j];
}
}
complete = true;
return;
}
if (c >= 9) {
dfs(r + 1, 0);
return;
}
if (sudoku[r][c] != 0) {
dfs(r, c + 1);
return;
}
int visited = row[r] | col[c] | grid[r / 3][c / 3];
int memoR = row[r];
int memoC = col[c];
int memoGrid = grid[r / 3][c / 3];
for (int i = 1; i <= 9; i++) {
if ((visited & 1 << i) != 0) continue;
test[r][c] = i;
row[r] |= 1 << i;
col[c] |= 1 << i;
grid[r / 3][c / 3] |= 1 << i;
dfs(r, c + 1);
row[r] = memoR;
col[c] = memoC;
grid[r / 3][c / 3] = memoGrid;
}
}
}