[백준 13460번] 구슬 탈출 2

2022. 2. 10. 13:28·알고리즘 문제풀이/백준
반응형

문제 링크: https://www.acmicpc.net/problem/13460

 

13460번: 구슬 탈출 2

첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B'

www.acmicpc.net

<문제 풀이> 시뮬레이션

상하좌우 기울이기 모든 조합을 다 해보면 되는데 한번 기울였을 때 RED, BLUE가 탈출에 성공했는지 여부를 저장할 bool 변수 2개가 필요하다.

 

1. 레드만 탈출 

-> 최솟값을 갱신

2. 블루가 탈출

-> 그 상태에서 4방향으로 기울이지 않고 종료한다.

 

[Left로 기울이기]

기울인 상태를 저장할 moved[10]을 준비

idx = 0 위치에 구슬을 저장할 수 있다.

각 행에 대해서 j =0  to j = M -1 모든 열을 확인한다.

만약 board[row][j]가 벽이면 idx = j + 1 위치에 구슬을 저장할 수 있다.

만약 board[row][j]가 구멍이면 idx = j 위치에 구슬을 넣어볼 수 있고, 현재 j의 위치에 구멍이 등장했다는 표시를 한다.

만약 board[row][j]가 구슬이고 idx에 구멍이 있으면 구슬을 넣는다

만약 board[row][j]가 구슬이고 idx에 구멍이 없으면 moved[idx++]에 구슬을 넣는다.

 

배열을 90도 회전하는 걸 구현하면

left 기울이기 하나만 구현해도 right, up, down을 구현할 수 있다

 

 

<C++ 소스 코드>

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include<iostream>
#include<algorithm>
using namespace std;
 
int N, M;
char board[10][10];
const int INF = (1 << 30);
int res = INF;
bool left(bool &red, bool& blue) {
    for (int i = 1; i < N - 1; i++) {
        char moved[10];
        int idx = 0;
        int escapeIdx = -1;
        fill(moved, moved + 10, '.');
        for (int j = 0; j < M; j++) {
            if (board[i][j] == '#') {
                moved[j] = '#';
                idx = j + 1;
            }
            else if (board[i][j] == 'O') {                
                moved[j] = 'O';
                escapeIdx = j;
                idx = j;
            }
            else if (board[i][j] == 'R' || board[i][j] == 'B') {
                if (idx != escapeIdx) {
                    moved[idx++] = board[i][j];
                }
                else {
                    if (board[i][j] == 'R') red = true;
                    else if (board[i][j] == 'B') blue = true;
                }
                
            }
        }
        for (int j = 0; j < M; j++) {
            board[i][j] = moved[j];
        }
    }
    if (blue || red) return true;
    else return false;
}
void rotate() {
    char temp[10][10];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            temp[i][j] = board[i][j];
        }
    }
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            board[j][N - 1 -i] = temp[i][j];
        }
    }
 
    swap(N, M);
 
}
 
bool down(bool &red, bool &blue) {
    rotate();
    bool ret =left(red, blue);
    rotate();
    rotate();
    rotate();
    return ret;
}
 
bool right(bool& red, bool& blue) {
    rotate();
    rotate();
    bool ret = left(red, blue);
    rotate();
    rotate();
    return ret;
}
bool up(bool& red, bool& blue) {
    rotate();
    rotate();
    rotate();
    bool ret = left(red, blue);
    rotate();
    return ret;
}
 
void backup(char temp[10][10]) {
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            board[i][j] = temp[i][j];
        }
    }
}
 
void solve(int idx) {
    if (idx == 11) return;
    char temp[10][10];
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            temp[i][j] = board[i][j];
        }
    }
    bool red = false;
    bool blue = false;
    if (!left(red, blue)) {
        solve(idx + 1);
    }
    if (red && !blue) {
        res = min(res, idx);
        return;
    }
    red = false;
    blue = false;
    backup(temp);
 
    if (!up(red, blue)) {
        solve(idx + 1);
    }
    if (red && !blue) {
        res = min(res, idx);
        return;
    }
    red = false;
    blue = false;
    backup(temp);
 
    if (!right(red, blue)) {
        solve(idx + 1);
    }
    if (red && !blue) {
        res = min(res, idx);
        return;
    }
    red = false;
    blue = false;
    backup(temp);
 
    if (!down(red, blue)) {
        solve(idx + 1);
    }
    if (red && !blue) {
        res = min(res, idx);
        return;
    }
    red = false;
    blue = false;
    backup(temp);
}
 
int main(void){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> board[i][j];
        }
    }
 
    solve(1);
    if (res == INF) {
        cout << -1 << '\n';
    }
    else {
        cout << res << '\n';
    }
    return 0;
}
Colored by Color Scripter
cs

 

반응형
저작자표시 (새창열림)

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 16946번] 벽 부수고 이동하기 4  (0) 2022.03.11
[백준 16234번] 인구 이동  (0) 2022.03.04
[백준 16973번] 직사각형 탈출  (0) 2022.01.31
[백준 16932번] 모양 만들기  (0) 2022.01.31
[백준 3190번] 뱀  (0) 2022.01.19
'알고리즘 문제풀이/백준' 카테고리의 다른 글
  • [백준 16946번] 벽 부수고 이동하기 4
  • [백준 16234번] 인구 이동
  • [백준 16973번] 직사각형 탈출
  • [백준 16932번] 모양 만들기
슥지니
슥지니
개발 블로그
  • 슥지니
    슥지니의 코딩노트
    슥지니
  • 전체
    오늘
    어제
    • 분류 전체보기 (199)
      • 알고리즘 문제풀이 (158)
        • 백준 (158)
      • 알고리즘 (6)
      • Node.js (2)
        • MongoDB (1)
        • 기타 (1)
      • spring (0)
      • 가상화폐 (1)
        • 바이낸스(Binance) (1)
      • C++ 테트리스 게임 (1)
      • C++ (10)
      • 안드로이드 프로그래밍 (21)
        • 코틀린 (21)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    BFS
    dfs
    구현
    코틀린을 활용한 안드로이드 프로그래밍
    그래프
    콘솔
    자료구조
    알고리즘
    다이나믹 프로그래밍
    dp
    그리디
    우선순위 큐
    코틀린
    백준
    C
    콘솔 테트리스 게임
    Kotlin
    백트랙킹
    시뮬레이션
    C++
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
슥지니
[백준 13460번] 구슬 탈출 2
상단으로

티스토리툴바