15684번: 사다리 조작

이거는 약간 구현에 신경써야 하는 문제이다.

여러번 풀어보는 것도 나쁘지 않다고 생각한다.

일단 하나씩 다 돌아보는 단순한 브루트포스 알고리즘으로 풀리는 문제이다. 다만 각 가로줄들을 데이터로 잘 표현하여 탐색을 돌리는 구현이 깔끔하게끔 짜야하는 문제가 있다.

각 가로줄을 일일이 저장하는 것이 아닌 특정 점에서 밑으로 내려올 수 있다 없다 로 가로줄을 판단할 수 있다.

예를 들어 check[3][4]=1 이라면 (3,4) 에서 사다리 밑으로 내려올 수 있다는 의미가 될 수 있다.

이를 이용해 check[x][y], check[x][y-1], check[x][y+1] 이 3개의 값을 비교하여 1인 경우 dfs 탐색을 돌리는 식으로 로직을 구성하면 문제를 풀 수 있다.

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>

using namespace std;

int n, m, h; 
int arr[100][100];
int check[100][100];
int _min = 1000000;
bool isok() {
    int cx;
    for (int i = 1; i <= n; i++) {
        cx = i;
        for (int j = 1; j <= h; j++) {
            if (check[j][cx] == 1) cx = cx + 1;
            else if (check[j][cx-1] == 1) cx = cx - 1;
        }
        if (cx != i) return false;
    }
    return true;
}
void dfs(int x, int cnt) {
    if (cnt >= 4) {
        return;
    }
    if (isok()) {
        _min = min(_min, cnt);
        return;
    }

    for (int i = x; i <= h; i++) {
        for (int j = 1; j < n; j++) {
            // check[x][y] = 1 
            if (check[i][j] == 1) continue;
            if (check[i][j-1] == 1) continue;
            if (check[i][j+1] == 1) continue;

            check[i][j] = 1;
            dfs(i, cnt + 1);
            check[i][j] = 0;
        }
    }
}
int main() {
    int a, b;

    cin >> n >> m >> h;
    for (int i = 0; i < m; i++) {
        cin >> a >> b;
        check[a][b] = 1;
    }
    dfs(1, 0); 
    if (_min == 1000000) cout << -1;
    else cout << _min;

    return 0;
}

'책장 > 알고리즘' 카테고리의 다른 글

[프로그래머스] 큰수만들기  (0) 2021.08.11
[백준-1082] 방번호  (0) 2021.08.10
[백준-2805] 나무자르기  (0) 2021.08.08
[백준-2517] 달리기  (0) 2021.08.08