알고리즘 풀이/Java
[알고리즘][X] 스도쿠
Dong's Universe
2024. 3. 27. 11:45
https://www.acmicpc.net/problem/2239
2239번: 스도쿠
스도쿠는 매우 간단한 숫자 퍼즐이다. 9×9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3×3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다
www.acmicpc.net
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static final int MAX_N = 9 * 9;
static boolean[][][] section;
static boolean[][] row;
static boolean[][] col;
static int[][] zeros;
static int[][] map;
static int zeroCount = 0;
static boolean flag;
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
section = new boolean[3][3][10];
row = new boolean[10][10];
col = new boolean[10][10];
zeros = new int[MAX_N][];
map = new int[10][10];
for (int i = 1; i <= 9; i++) {
String line = br.readLine();
for (int j = 1; j <= 9; j++) {
int n = line.charAt(j-1) - '0';
if (n == 0) {
zeros[zeroCount++] = new int[] {i, j};
continue;
}
section[(i-1) / 3][(j-1) / 3][n] = true;
row[i][n] = true;
col[j][n] = true;
map[i][j] = n;
}
}
dfs(0);
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
sb.append(map[i][j]);
}
sb.append("\n");
}
System.out.println(sb);
}
private static void dfs(int depth) {
if (depth == zeroCount) {
flag = true;
return;
}
int[] zero = zeros[depth];
int r = zero[0];
int c = zero[1];
for (int i = 1; i <= 9; i++) {
if (row[r][i] == true || col[c][i] == true || section[(r-1)/3][(c-1)/3][i] == true) {
continue;
}
row[r][i] = true;
col[c][i] = true;
section[(r-1)/3][(c-1)/3][i] = true;
map[r][c] = i;
dfs(depth+1);
if (flag) return;
row[r][i] = false;
col[c][i] = false;
section[(r-1)/3][(c-1)/3][i] = false;
map[r][c] = 0;
}
}
}
나의 풀이
- -1/3 = 0이다. -3/3=-1이다.
- 여러개가 성공일 수 있기 때문에 일단 하나라도 완성이 되면 재귀를 끝내주어야 한다. 그러지 않아서 시간 초과가 났다.
- 답은 하나라는데 사전순이다. 그렇다면 zeros를 넣은 순서대로 재귀를 들어가주면 정답이 된다. 조심하자!!