프로그래머스 레벨2 리코쳇 로봇
프로그래머스 레벨2 연습문제
장애물이나 맨 끝에 부딪힐 때까지 미끄러져 이동을 통해 최단거리 구하기
기존의 BFS에서 한번 더 업그레이드 된 문제
https://school.programmers.co.kr/learn/courses/30/lessons/169199
1. 문제
간단 설명
포켓몬스터 얼음 퍼즐처럼 움직인다
장애물(‘D’)이나, 맨 끝에 부딪힐 때 까지 미끄러진다
BFS를 이용해서 최단거리를 탐색할 때,
언제 방문처리를 할 것인지,
dy, dx를 어떻게 갱신할 것인가가 포인트
2. 문제 분석
필요변수
vector<string> board
로 입력이 주어짐
기본적인 변수들은 BFS와 같음
맵 정보를 저장할 char map[y][x]
, 방문표시 처리를 할 int visited[y][x]
좌표 구조체 struct node
대신 pair<int, int>
를 이용해 좌표 처리
4방향 표현을 위한 direct[4][2]
시작 로봇의 위치와 도착점 등
주의점
- 입력이 알파벳 문자열로 주어짐
- 이를 잘라서 int 배열에 잘 변환해서 넣을것
- 기존의 BFS에서는 한칸씩 움직였지만, 이번에는 쭉 미끄러지는걸 한번의 이동으로 침
- 이를 어떻게 구현할 것인지가 포인트
- 또한 방문 처리를 언제 할 것인지가 포인트
알고리즘
1
2
3
4
5
6
7
8
9
10
1. 입력받기
2. 로봇의 시작지점을 방문처리후, 이 지점부터 BFS 시작
3. BFS 시작. 큐에서 맨 앞을 꺼낸다
3-1. dy, dx 를 큐에서 꺼낸 now의 좌표로 설정
3-2. 이 좌표(dy, dx)에 y, x 갱신값을(direct[t]) 경계, 또는 벽을 만날때까지 계속 더해본다
3-3. 벽 또는 경계를 만났다면 멈춘다
3-4. 이 dy, dx가 목표지점인지 체크
- 목표 지점이라면 이동거리를 리턴
3-5. 이미 방문한곳이라면 패스
3-6. 방문처리 후, dy, dx, 레벨 + 1 을 큐에 넣는다
3. 소스코드
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
#include <iostream>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define MAX 101
char map[MAX][MAX]; // 맵 저장용
int visited[MAX][MAX]; // 방문처리 + 몇번 이동했는지 체크용
int N, M; // 맵 사이즈 저장용
int start_y, start_x, dest_y, dest_x; // 시작지점과 도착지점 표시
int direct[4][2] = {0,1,1,0,0,-1,-1,0};
int BFS() {
queue<pair<int, int>> qu;
qu.push({ start_y, start_x });
visited[start_y][start_x] = 1;
while (!qu.empty()) {
pair<int, int> now = qu.front();
qu.pop();
if (now.first == dest_y && now.second == dest_x) {
return visited[now.first][now.second] ;
}
for (int t = 0; t < 4; t++) {
int dy = now.first;
int dx = now.second;
while (true) {
dy += direct[t][0];
dx += direct[t][1];
if (dy < 0 || dx < 0 || dy >= N || dx >= M) break;
if (map[dy][dx] == 'D') break;
}
dy -= direct[t][0];
dx -= direct[t][1];
if (visited[dy][dx]) continue;
visited[dy][dx] = visited[now.first][now.second] + 1;
qu.push({ dy, dx });
}
}
return 0;
}
int main(){
// 비쥬얼 스튜디오에서 코딩해서 이렇게 수정했음
freopen_s(new FILE*, "input.txt", "r", stdin);
vector<string> board = {
"...D..R",
".D.G...",
"....D.D",
"D....D.",
"..D...."
};
// 입력받기
N = board.size();
M = board[0].size();
for (int y = 0; y < N; y++) {
for (int x = 0; x < M; x++) {
map[y][x] = board[y][x];
if (map[y][x] == 'R') {
start_y = y;
start_x = x;
}
else if (map[y][x] == 'G') {
dest_y = y;
dest_x = x;
}
}
}
// BFS
cout << BFS() - 1;
// -1 해주는 이유?
// 따로 이동횟수를 카운팅하는 변수를 사용하지 않고, 방문체크 배열에 같이 기록함
// 첫 시작부터 한칸으로 체크되므로, 도착시 -1 해줘야 올바른 값이 출력됨
return 0;
}
프로그래머스에서 IDE 없이 직접 푸는게 아직 익숙하지 않아
어려운데 더 어려워졌다
IDE를 사용하지 않고 디버깅하는 방법에 익숙해져야할듯 하다
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.