반응형
https://www.acmicpc.net/problem/13460
13460번: 구슬 탈출 2
첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B'
www.acmicpc.net
[ 문제풀이 ]
BFS를 이용한 구현 문제였습니다.
먼저 move 함수를 통해서 공들을 옮겨줍니다. 공을 움직이고 나서 각 공의 좌표를 visited 배열에 저장해서 이전에 똑같은 상황이 있었다면 queue에 넣지 않는 식으로 구현하였습니다.
또한, 공을 움직인 횟수가 10회를 초과했다면 continue 하였고, 둘 다 구멍에 들어갔다면 마찬가지로 continue 해주었습니다.
[ 소스 코드 ]
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 | #include<iostream> #include<queue> using namespace std; struct state { int Ry; int Rx; int By; int Bx; int cnt; }; int N, M; char map[10][10]; char temp[10][10]; int visited[10][10][10][10]; int dy[4] = { -1,1,0,0 }; int dx[4] = { 0,0,-1,1 }; int Ry; int Rx; int By; int Bx; int ans; void move(int num) //구슬을 움직이기 위한 move 함수 { for (int i = 1; i < 10; i++) { //빨간 구슬 옮기기 int yy = Ry + dy[num] * i; int xx = Rx + dx[num] * i; if (temp[yy][xx] == 'O') { temp[Ry][Rx] = '.'; Ry = 0; Rx = 0; break; } else if (temp[yy][xx] != '.') { temp[Ry][Rx] = '.'; Ry = Ry + dy[num] * (i - 1); Rx = Rx + dx[num] * (i - 1); temp[Ry][Rx] = 'R'; break; } } for (int i = 1; i < 10; i++) { //파란 구슬 옮기기 int yy = By + dy[num] * i; int xx = Bx + dx[num] * i; if (temp[yy][xx] == 'O') { temp[By][Bx] = '.'; By = 0; Bx = 0; break; } else if (temp[yy][xx] != '.') { temp[By][Bx] = '.'; By = By + dy[num] * (i - 1); Bx = Bx + dx[num] * (i - 1); temp[By][Bx] = 'B'; break; } } } int main() { cin >> N >> M; queue<state> q; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { cin >> map[i][j]; if (map[i][j] == 'R') { map[i][j] = '.'; Ry = i; Rx = j; } else if (map[i][j] == 'B') { map[i][j] = '.'; By = i; Bx = j; } } } q.push({ Ry,Rx,By,Bx,0 }); visited[Ry][Rx][By][Bx] = 1; while (!q.empty()) { int curRy = q.front().Ry; int curRx = q.front().Rx; int curBy = q.front().By; int curBx = q.front().Bx; int cnt = q.front().cnt; q.pop(); if (curRy == 0 && curBy != 0) { //빨간 구슬만 들어갔을 때 cnt출력 cout << cnt; return 0; } else if (curRy == 0 && curBy == 0 || cnt >= 10) { continue; //둘 다 들어갔거나 10번 초과이면 continue } for (int i = 0; i < 4; i++) { for (int j = 0; j < N; j++) { //map배열을 temp배열에 복사 for (int k = 0; k < M; k++) { temp[j][k] = map[j][k]; } } Ry = curRy; Rx = curRx; By = curBy; Bx = curBx; temp[Ry][Rx] = 'R'; //구슬을 배치 temp[By][Bx] = 'B'; for (int j = 0; j < 2; j++) { //완벽하게 움직이기 위해서 두번 움직임 move(i); } if (visited[Ry][Rx][By][Bx] != 1) {//이전에 같은 상태가 있었다면 q에 넣지 않기 visited[Ry][Rx][By][Bx] = 1; q.push({ Ry,Rx,By,Bx,cnt + 1 }); } } } cout << -1; //10번 초과했거나 항상 두 구슬이 다 들어가는 경우 } | cs |
반응형
'백준' 카테고리의 다른 글
[ 백준 ] 9935번 - 문자열 폭발 (C++) (0) | 2022.06.14 |
---|---|
[ 백준 ] 2638번 - 치즈 (C++) (0) | 2022.06.13 |
[ 백준 ] 11404번 - 플로이드 (C++) (0) | 2022.06.11 |
[ 백준 ] 1865번 - 웜홀 (C++) (0) | 2022.06.10 |
[ 백준 ] 1238번 - 파티 (C++) (0) | 2022.06.09 |