[백준][15684] 사다리 조작
 [백준][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  라이센스를 따릅니다.

