• 문제 링크
15684번: 사다리 조작
사다리 게임은 N개의 세로선과 M개의 가로선으로 이루어져 있다. 인접한 세로선 사이에는 가로선을 놓을 수 있는데, 각각의 세로선마다 가로선을 놓을 수 있는 위치의 개수는 H이고, 모든 세로선
www.acmicpc.net
• 풀이 과정
n개의 세로선에 h개의 점선이 가로로 교차되어 있는 사다리에 m개의 가로선의 정보를 입력받는다.
2차원 boolean 배열에 입력받은 좌표 기준 오른쪽 방향에 가로선이 있을 시 true 로 저장한다.
가로선은 없거나 최대 3개까지 사용 가능하므로 가로선이 0 ~ 3개 추가로 설치한 경우를 모두 확인한다.
재귀 함수(recur) 의 2중 for문에서 현재 위치 기준 오른쪽 방향으로 가로선이 존재하지 않을 경우 (!map[i][j])
백트래킹을 통하여 특정 층에서 가로선을 설치하는 모든 경우의 수를 확인한다.
재귀를 통해 증가된 가로선의 개수(cnt) 가 현재 목표 가로선(min = i) 의 개수와 일치하다면
현재 사다리를 통해 모든 i번 세로선 경로의 결과가 i인지 확인한다.(isPass)
각 층의 현재 위치에서 오른쪽(map[y][x]), 왼쪽(map[y][x - 1]) 으로 이동 가능한 가로선이 있는 지 확인하며
존재하는 가로선 경로로 한층씩 내려간다.(y++)
만약 각각의 i번 세로선 경로의 결과가 i 일 경우 true 를 반환, 아닌 경우 false 를 반환한다.
이렇게 최소 가로선의 개수가 구해진다면 해당 값을, 구하지 못하였다면 -1 을 정답으로써 출력한다.
• 풀이 코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
static int n, m, h;
static boolean[][] map;
static boolean finish;
static int min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
h = Integer.parseInt(st.nextToken());
map = new boolean[h + 1][n + 1];
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int y = Integer.parseInt(st.nextToken());
int x = Integer.parseInt(st.nextToken());
map[y][x] = true;
}
for (int i = 0; i <= 3; i++) {
min = i;
recur(1, 0);
if (finish)
break;
}
bw.write((finish ? min : -1) + "\n");
bw.flush();
}
private static void recur(int idx, int cnt) {
if (finish)
return;
if (min == cnt) {
if (isPass())
finish = true;
return;
}
for (int i = idx; i <= h; i++) {
for (int j = 1; j < n; j++) {
if (!map[i][j]) {
map[i][j] = true;
recur(i, cnt + 1);
map[i][j] = false;
}
}
}
}
private static boolean isPass() {
for (int i = 1; i <= n; i++) {
int y = 1;
int x = i;
for (int j = 0; j < h; j++) {
if (map[y][x])
x++;
else if (map[y][x - 1])
x--;
y++;
}
if (x != i)
return false;
}
return true;
}
}
'Problem Solving > Baekjoon' 카테고리의 다른 글
[백준] 17136 색종이 붙이기 - Backtracking / Java (0) | 2022.09.21 |
---|---|
[백준] 16945 매직 스퀘어로 변경하기 - Backtracking / Java (0) | 2022.09.20 |
[백준] 14889 스타트와 링크 - Backtracking / Java (0) | 2022.09.18 |
[백준] 1759 암호 만들기 - Backtracking / Java (0) | 2022.09.17 |
[백준] 16958 텔레포트 - Brute Force / Java (0) | 2022.09.16 |
댓글