길민호(ethan.mino)
코딩수첩
길민호(ethan.mino)
전체 방문자
오늘
어제
  • 분류 전체보기 (215)
    • Computer Science (0)
    • Web (6)
      • CSS (0)
      • HTML (0)
    • Node.js (0)
    • Javascript (2)
    • Java (46)
      • Spring (27)
      • Jsp (0)
    • C\C++ (2)
    • Programming (0)
    • AI (0)
    • Database (7)
    • Git (5)
    • Algorithm (119)
      • Stack (0)
      • Queue (0)
      • Linked List (0)
      • Sort (0)
      • Simulation (27)
      • Recursion (0)
      • Backtracking (4)
      • Two Pointer (3)
      • Dynamic Programming (19)
      • Greedy (10)
      • Graph (3)
      • Dijkstra (1)
      • BFS\DFS (8)
      • Floyd (1)
      • MST (4)
      • Tree (4)
      • Binary Search (8)
      • Binary Search Tree (4)
    • IntelliJ (4)
    • Vscode (0)
    • Operating System (0)
    • 후기 (3)
    • 성장일지 (13)
    • 스터디 (7)
    • 설치 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㅡ

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
길민호(ethan.mino)

코딩수첩

Algorithm/Simulation

[백준 15684번] 사다리 조작 (C/C++)

2022. 3. 23. 02:12

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

 

15684번: 사다리 조작

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

www.acmicpc.net


사다리 조작 문제는 백트래킹을 이용하여 가로선을 선택하는 모든 경우의 수(Combination)에 대해 사다리 타기를 수행하면 문제를 해결할 수 있습니다. 

 

전체 코드는 아래와 같습니다.

#include <bits/stdc++.h>
using namespace std;

#define b first
#define a second

int board[30][10];  // board[b-1][a-1]은 b번과 b+1번을 연결하는 a번째 가로선의 유무
int n, m, h, ans = INT_MAX;

bool ladder(int board[][10]){
    for(int i = 0; i < h; i++)  // 두 가로선이 연속하는지 확인
        for(int j = 0; j < (n - 2); j++)
            if(board[i][j] == 1 && board[i][j + 1] == 1)
                return false;

    for(int i = 0; i < n; i++){
        pair<int, int> cur = {0, i};    // 사다리가 cur의 왼쪽 상단에 위치 한다고 가정
        while(true){
            if(cur.b < 0 || cur.a < 0 || cur.b >= h || cur.a >= n) break;   // 사다리를 벗어나는 경우 더이상 진행하지 않음
            
            if(board[cur.b][cur.a] == 1)   // 오른쪽 가로선이 존재하는 경우
                cur = {cur.b, cur.a + 1};   // 오른쪽으로 이동
            else if(cur.a - 1 >= 0 && cur.a - 1 < n && board[cur.b][cur.a - 1] == 1)    // 왼쪽 가로선이 존재하는 경우
                cur = {cur.b, cur.a - 1};   // 왼쪽으로 이동
            
            cur = {cur.b + 1, cur.a};   // 아래로 이동
        }
        if(cur.a != i) return false; // i번 세로선의 결과가 i가 아닌 경우
    }
    return true;    // 모든 세로선의 결과가 i번이 나왔으므로 true 반환
}

void back(int board[30][10], int line, int num){  // line은 세로선의 번호(0 ~ n-1), num은 남은 가로선의 개수
    if(num > 0 && line < n){    // 배치할 가로선이 남아있고, 존재하는 세로선인 경우
        for(int i = 0; i <= num; i++){  // line번과 line + 1번 라인을 잇는 가로선 i개를 선택
            vector<int> np; // Combination을 위한 벡터
            for(int j = 0; j < h - i; j++) np.push_back(0); // 가로선은 h개 가능
            for(int j = 0; j < i; j++) np.push_back(1); // 가로선 i개 선택

            do{
                int temp[30][10]; memcpy(temp, board, sizeof(temp));
                bool overlap = false; 

                for(int j = 0; j < np.size(); j++){ // 추가된 가로선이 기존에 있던 가로선(입력 받은 가로선)과 겹치는 지 확인
                    if(np[j] == 1){
                        if(temp[j][line] == 1) overlap = true;
                        else temp[j][line] = 1;
                    }
                }

                if(!overlap){   // 하나라도 겹치지 않는다면
                    // 사다리 타기 수행 결과 모든 세로선의 결과가 i가 나온 경우 ans를 업데이트
                    if(ladder(temp)) ans = min(ans, 3 - (num - i)); 
                    // 그렇지 않은 경우 남은 가로선의 개수를 줄이고, 다음 라인으로 옮김
                    else back(temp, line + 1, num - i);
                }
            }while(next_permutation(np.begin(), np.end())); // 현재 라인에서 가로선을 i개 선택하는 Combination의 각 경우의 수에 대해 반복
        }
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m >> h;
    
    while(m--){
        int x, y; cin >> x >> y;
        board[x - 1][y - 1] = 1;    // 입력된 가로선을 배열에 표시
    }
    
    back(board, 0, 3);
    cout << ((ans == INT_MAX) ? -1 : ans);
}

'Algorithm > Simulation' 카테고리의 다른 글

[백준 5373번] 큐빙 (C/C++)  (0) 2022.03.25
[백준 15685번] 드래곤 커브 (C/C++)  (0) 2022.03.23
[백준 14890번] 경사로 (C/C++)  (0) 2022.03.21
[백준 14502번] 연구소 (C/C++)  (0) 2022.03.20
[백준 13460번] 구슬 탈출 2 (C/C++)  (0) 2022.03.20
    'Algorithm/Simulation' 카테고리의 다른 글
    • [백준 5373번] 큐빙 (C/C++)
    • [백준 15685번] 드래곤 커브 (C/C++)
    • [백준 14890번] 경사로 (C/C++)
    • [백준 14502번] 연구소 (C/C++)
    길민호(ethan.mino)
    길민호(ethan.mino)
    💻 호기심 많은 서버 개발자 길민호입니다.

    티스토리툴바