※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 15684번 문제인 사다리 조작이다.
문제는 아래 링크를 확인하자.

www.acmicpc.net/problem/15684

 

15684번: 사다리 조작

사다리 게임은 N개의 세로선과 M개의 가로선으로 이루어져 있다. 인접한 세로선 사이에는 가로선을 놓을 수 있는데, 각각의 세로선마다 가로선을 놓을 수 있는 위치의 개수는 H이고, 모든 세로선

www.acmicpc.net

처음 이 문제를 읽을 때, "만약, 정답이 3보다 큰 값이면 -1을 출력한다." 부분을 놓쳐 어떻게 풀어야 좋을지 많은 고민을 했던 기억이 있다. 하지만 이 문제에서는 선을 3개까지만 그어보면 되므로, 모든 경우의 수를 전부 수행해보아도 제한시간 내에 문제를 해결할 수 있다.

 

사다리의 가로 선을 배열에 입력받을 때, 오른쪽 방향으로 이동해야 하는 막대기에는 1을, 왼쪽 방향으로 이동해야하는 막대기에는 -1을 집어넣고, 그 외에는 초기값으로 0을 주어 사다리가 문제에 조건에 맞는지 확인하기 위해 확인할 때 각 높이에 적혀있는 숫자를 더하는 식으로 사다리타기를 구현할 수 있다.

 

아래는 제출한 소스코드이다.

#include <iostream>
using std::cin; using std::cout;

int ladder[11][31]; // ladder[N번줄][i번행에서 +1이면 i+1번줄로 이동, -1이면 i-1번줄로 이동]

int N, M, H;

bool game() {
    for (int i = 1;i < N;i++) {
        int x = i;
        int h = 1;
        while (h <= H) {
            x += ladder[x][h];
            h++;
        }
        if (x != i) return 0;
    }
    return 1;
}

bool ladder1() {
    for (int i = 1;i < N;i++) {
        for (int h = 1;h <= H;h++) {
            if (ladder[i][h] == 0 and ladder[i + 1][h] == 0) { // 선을 그을 수 있는 곳이면
                ladder[i][h] = 1; ladder[i + 1][h] = -1;
                if (game()) return 1;
                ladder[i][h] = 0; ladder[i + 1][h] = 0;
            }
        }
    }
    return 0;
}

int cnt = 0;

bool ladder2(int i) {
    if (cnt == 2) {
        if (game()) return 1;
        else return 0;
    }
    for (;i < N;i++) {
        for (int h = 1;h <= H;h++) {
            if (ladder[i][h] == 0 and ladder[i + 1][h] == 0) { // 선을 그을 수 있는 곳이면
                ladder[i][h] = 1; ladder[i + 1][h] = -1;
                cnt++;
                if (ladder2(i)) return 1;
                cnt--;
                ladder[i][h] = 0; ladder[i + 1][h] = 0;
            }
        }
    }
    
    return 0;
}

bool ladder3(int i) {
    if (cnt == 3) {
        if (game()) return 1;
        else return 0;
    }
    for (;i < N;i++) {
        for (int h = 1;h <= H;h++) {
            if (ladder[i][h] == 0 and ladder[i + 1][h] == 0) { // 선을 그을 수 있는 곳이면
                ladder[i][h] = 1; ladder[i + 1][h] = -1;
                cnt++;
                if (ladder3(i)) return 1;
                cnt--;
                ladder[i][h] = 0; ladder[i + 1][h] = 0;
            }
        }
    }

    return 0;
}

int main()
{
    std::ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N >> M >> H;
    for (int i = 0;i < M;i++) {
        int a, b; cin >> a >> b;
        ladder[b][a] = 1;
        ladder[b+1][a] = -1;
    }
    if (game()) cout << 0;
    else {
        cnt = 0;
        if (ladder1()) cout << 1;
        else {
            cnt = 0;
            if (ladder2(1)) cout << 2;
            else {
                cnt = 0;
                if (ladder3(1)) cout << 3;
                else cout << -1;
            }
        }
    }

    return 0;
}
728x90

+ Recent posts