[백준][15684] 사다리 조작
이 포스트는 백준 사이트의 사다리 조작 문제 풀이입니다.
문제
해결 과정
이 문제는 주어진 상황에서 N개의 사다리가 시작 번호와 도착 번호가 동일하도록 만들기 위한
최소의 사다리 추가 수를 구하는 문제입니다.
따라서 이 문제에서는 2가지 과정이 필요합니다.
- 현재 상태에서 N개가 각자 동일한 번호(시작 번호 = 도착 번호)인지 확인 후 추가된 사리 수 갱신
- 현 위치에 사다리를 추가할 수 있다면, 추가하고 1번을 실행
2번 과정에서 사다리를 추가할 수 있는 조건은 아래와 같습니다.
현 위치에서 연결된 사다리가 없음(i: 현위치, i-1 -> i 혹은 i <- i+1 연결된 사다리)
즉, 사다리가 전혀 없는 위치에서만 사다리를 추가할 수 있습니다.
이 문제를 해결하고자 저는 모든 경우의 수를 확인하고 매번 유효성을 확인 뒤 조건에 맞는 상태만 검사하는
백트래킹 기법을 사용하였습니다.
코드 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include <vector>
#define MAX 31
using namespace std;
int N, M, H, answer = 2e9;
vector<vector<bool>> visited;
void input();
void select_line(int curr_line_num, int ladder_cnt);
bool success_ladder_game();
int main() {
input();
select_line(1, 0);
answer = (answer > 3 ? -1 : answer);
cout << answer;
return 0;
}
void input() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> N >> M >> H;
visited.assign(H + 1, vector<bool>(N + 1, false));
for(int i = 0; i < M; ++i) {
int depth, line_number;
cin >> depth >> line_number;
visited[depth][line_number] = true;
}
}
void select_line(int curr_line_num, int ladder_cnt) {
if(ladder_cnt > 3) {
return;
} else if(success_ladder_game()) {
answer = min(answer, ladder_cnt);
return;
}
for(int line_num = curr_line_num; line_num < N; ++line_num) {
for(int depth = 1; depth <= H; ++depth) {
if(visited[depth][line_num]
|| visited[depth][line_num + 1]
|| visited[depth][line_num - 1]) continue;
visited[depth][line_num] = true;
select_line(line_num, ladder_cnt + 1);
visited[depth][line_num] = false;
}
}
}
bool success_ladder_game() {
for(int line_num = 1; line_num <= N; ++line_num) {
int start_line_num = line_num;
for(int depth = 1; depth <= H; ++depth) {
if(visited[depth][start_line_num])
start_line_num += 1;
else if(visited[depth][start_line_num - 1])
start_line_num -= 1;
}
if(line_num != start_line_num)
return false;
}
return true;
}
실행 결과
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.