목차
- 문제
- 내가 푼 방법
- 자바 코드
- 결과 및 회고
1. 문제
https://www.acmicpc.net/problem/15684
2. 내가 푼 방법
완전 탐색이 필요한 문제이다. 이 문제를 풀 때는 가로, 세로 길이를 주의해야 한다고 생각한다.
가로 길이 N과 세로 길이 H를 입력받고, boolean 자료형을 가진 사다리 배열을 선언해준다.
사다리 배열 범위를 N+1, H+1로 지정해 줬는데, arr[i][j] = true라면 세로줄 i와 i+1을 잇는 j번째 가로줄로 설정해두었다.
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
H = Integer.parseInt(st.nextToken());
arr = new boolean[H+1][N+1];
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
arr[a][b] = true;
}
사다리를 조작하기 전, result를 Integer.MAX_VALUE로 설정해두었다.
사다리를 조작할 수 있는 완전탐색 부분은 controlLadder에 있는 이중 for문 부분이며, 시간 초과를 해결하기 위해 x와 y 이후에 있는 사다리 값을 판단한다.
가로선이 연속하면 안 되므로 arr[i][j], arr[i][j-1], arr[i][j+1]을 확인해주어 가로선을 만들 수 있는지를 확인한다.
(※ 만들 수 있는 가로선을 확인할 때(controlLadder)와 i번째 사다리가 i번째 결과를 가지는지 확인할 때(checkLadder) i, j 범위가 다르다)
public static void solution() {
result = Integer.MAX_VALUE;
controlLadder(1, 1, 0);
}
public static void controlLadder(int x, int y, int cnt) {
if (checkLadder()) {
result = Math.min(result, cnt);
return;
}
if (cnt == 3) return;
for (int i = x; i <= H; i++) {
for (int j = 1; j < N; j++) {
if (i == x && j < y) continue;
if (j-1 > 0 && arr[i][j-1]) continue;
if (arr[i][j]) continue;
if (j+1 < N && arr[i][j+1]) continue;
arr[i][j] = true;
controlLadder(i, j, cnt+1);
arr[i][j] = false;
}
}
}
public static boolean checkLadder() {
for (int j = 1; j <= N; j++) {
int line = j;
for (int i = 1; i <= H; i++) {
if (arr[i][line-1]) line -= 1;
else if (arr[i][line]) line += 1;
}
if (line != j) return false;
}
return true;
}
3. 자바 코드
깃허브 풀이 주소
https://github.com/geujeog/BOJ/blob/main/B15684.java
import java.util.*;
import java.io.*;
class Main {
static int N;
static int H;
static int M;
static boolean[][] arr;
static int result;
public static void main (String[] args) throws IOException {
init();
solution();
print();
}
public static void solution() {
result = Integer.MAX_VALUE;
controlLadder(1, 1, 0);
}
public static void controlLadder(int x, int y, int cnt) {
if (checkLadder()) {
result = Math.min(result, cnt);
return;
}
if (cnt == 3) return;
for (int i = x; i <= H; i++) {
for (int j = 1; j < N; j++) {
if (i == x && j < y) continue;
if (j-1 > 0 && arr[i][j-1]) continue;
if (arr[i][j]) continue;
if (j+1 < N && arr[i][j+1]) continue;
arr[i][j] = true;
controlLadder(i, j, cnt+1);
arr[i][j] = false;
}
}
}
public static boolean checkLadder() {
for (int j = 1; j <= N; j++) {
int line = j;
for (int i = 1; i <= H; i++) {
if (arr[i][line-1]) line -= 1;
else if (arr[i][line]) line += 1;
}
if (line != j) return false;
}
return true;
}
public static void print() throws IOException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
if (result == Integer.MAX_VALUE) bw.write(-1+"");
else bw.write(result+"");
bw.flush();
bw.close();
}
public static void init() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
H = Integer.parseInt(st.nextToken());
arr = new boolean[H+1][N+1];
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
arr[a][b] = true;
}
br.close();
}
}
4. 결과 및 회고
사다리 가로선을 이을 수 있는 범위를 설정하는 것이 관건인 것 같다. 분명 arr[i][j] = true면 세로줄 i와 i+1을 잇는 j번째 가로선이었는데 헷갈려서 삽질을 했던 부분도 있었다. 다른 분들은 그러지 마시길! ㅎㅎ
'문제풀이 > 백준' 카테고리의 다른 글
[JAVA] BOJ 백준 2011번 - 암호코드 (0) | 2023.09.27 |
---|---|
[JAVA] BOJ 백준 16928번 - 뱀과 사다리 게임 (0) | 2023.09.27 |
[JAVA] BOJ 백준 12851번 - 숨바꼭질2 (0) | 2023.09.27 |
[JAVA] BOJ 백준 1109번 - 섬 (2) | 2023.07.28 |
[JAVA] BOJ 백준 11404번 - 플로이드 (0) | 2023.06.20 |
댓글