취업/Algorithm.

백준 15684. 사다리 조작

Azderica 2020. 4. 11. 00:13

사다리 조작

 


Problem?

문제 :  https://www.acmicpc.net/problem/15684
 

15684번: 사다리 조작

사다리 게임은 N개의 세로선과 M개의 가로선으로 이루어져 있다. 인접한 세로선 사이에는 가로선을 놓을 수 있는데, 각각의 세로선마다 가로선을 놓을 수 있는 위치의 개수는 H이고, 모든 세로선이 같은 위치를 갖는다. 아래 그림은 N = 5, H = 6 인 경우의 그림이고, 가로선은 없다. 초록선은 세로선을 나타내고, 초록선과 점선이 교차하는 점은 가로선을 놓을 수 있는 점이다. 가로선은 인접한 두 세로선을 연결해야 한다. 단, 두 가로선이 연속하거나 서로

www.acmicpc.net

 

Solution

dfs 문제

  1. dfs를 통해 모든 경로를 확인한다.
  2. 사다리는 순서가 없으므로 계속 내려가게 확인하면 된다.

Code

#include <iostream>
#include <algorithm>
using namespace std;

const int H_MAX = 30 + 2;
const int N_MAX = 10 + 2;

int N, M, H;
bool board[H_MAX][N_MAX];
int ans = 4;

bool isValidLadder(int i, int j) {
    if (board[i][j - 1] || board[i][j] || board[i][j + 1])
        return false;
    return true;
}

bool isCorrectLadder() {
    for (int j = 1; j <= N; j++) {
        int pos = j;
        for (int i = 1; i <= H; i++) {
            if (board[i][pos])
                pos++;
            else if (board[i][pos - 1])
                pos--;
        }
        if (pos != j)
            return false;
    }
    return true;
}


void dfs(int s_i, int cnt) {
    // end state
    if (cnt > 3) {
        return;
    }
    if (isCorrectLadder()) {
        ans = min(ans, cnt);
        return;
    }
    // recursive
    for (int i = s_i; i <= H; i++) {
        for (int j = 1; j <= N; j++) {
            if (isValidLadder(i, j)) {
                board[i][j] = true;
                dfs(i, cnt + 1);
                board[i][j] = false;
            }
        }
    }

}

int main(int argc, const char* argv[]) {
    int a, b;

    // input
    cin >> N >> M >> H;
    for (int i = 0; i < M; i++) {
        scanf("%d %d", &a, &b);
        board[a][b] = true;
    }

    // solution
    dfs(1, 0);

    // output
    if (ans == 4)
        cout << "-1\n";
    else
        cout << ans << "\n";

    return 0;
}

 


  • dfs 변형 문제