14503 - 로봇 청소기
본문
로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오.
로봇 청소기가 있는 장소는 $N \times M$ 크기의 직사각형으로 나타낼 수 있으며, $1 \times 1$크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 벽 또는 빈 칸이다. 청소기는 바라보는 방향이 있으며, 이 방향은 동, 서, 남, 북중 하나이다. 지도의 각 칸은 ($r, c$)로 나타낼 수 있고, $r$은 북쪽으로부터 떨어진 칸의 개수, $c$는 서쪽으로 부터 떨어진 칸의 개수이다.
로봇 청소기는 다음과 같이 작동한다.
- 현재 위치를 청소한다.
- 현재 위치에서 현재 방향을 기준으로 왼쪽방향부터 차례대로 탐색을 진행한다.
- 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
- 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.
- 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
- 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
로봇 청소기는 이미 청소되어있는 칸을 또 청소하지 않으며, 벽을 통과할 수 없다.
입력
첫째 줄에 세로 크기 $N$과 가로 크기 $M$이 주어진다. ($3 \leq N, M \leq 50$)
둘째 줄에 로봇 청소기가 있는 칸의 좌표 ($r, c$)와 바라보는 방향 $d$가 주어진다. $d$가 $0$인 경우에는 북쪽을, $1$인 경우에는 동쪽을, $2$인 경우에는 남쪽을, $3$인 경우에는 서쪽을 바라보고 있는 것이다.
셋째 줄부터 $N$개의 줄에 장소의 상태가 북쪽부터 남쪽 순서대로, 각 줄은 서쪽부터 동쪽 순서대로 주어진다. 빈 칸은 $0$, 벽은 $1$로 주어진다. 지도의 첫 행, 마지막 행, 첫 열, 마지막 열에 있는 모든 칸은 벽이다.
로봇 청소기가 있는 칸의 상태는 항상 빈 칸이다.
출력
로봇 청소기가 청소하는 칸의 개수를 출력한다.
제한
시간 제한 | 메모리 제한 |
---|---|
2sec | 512MB |
- $3 \leq N, M \leq 50$
풀이
문제에서 원하는 조건이 너무 명확하다. 조건분기도 모두 문제에 제시되어있고, 함정같은 부분도 없는 일반적인 시뮬레이션 문제이다. 문제에서 원하는 대로 그대로 따라가며 구현하면 된다. 조건만 헷갈리지 않도록 주의하자.
- 참고 알고리즘 :
코드
사용 언어 : C
최종 수정일 : 2023 / 1 / 30
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
#include <stdio.h>
typedef char bool;
const bool true = 1;
const bool false = 0;
typedef struct ND {
int x, y;
} ND;
const int North = 0;
const int East = 1;
const int South = 2;
const int West = 3;
ND dir[4] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} };
#define EMPTY 0
#define WALL 1
#define CLEANED 2
#define MAX_IDX 50
bool grid[MAX_IDX][MAX_IDX];
int n, m;
int r, c, d;
int retval;
void clean(int x, int y) {
if (grid[x][y] == EMPTY) {
grid[x][y] = CLEANED;
++retval;
}
return;
}
int main() {
scanf("%d %d", &n, &m);
scanf("%d %d %d", &r, &c, &d);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
scanf("%d", &grid[i][j]);
}
}
bool notExit = true;
while (notExit == true) {
clean(r, c);
int directionStack = 0;
bool allCleaned = true;
for (int directionStack = 1; directionStack <= 4; ++directionStack) {
int curD = ((d - directionStack) + 8) % 4;
if (grid[r + dir[curD].x][c + dir[curD].y] == EMPTY) {
allCleaned = false;
d = curD;
r += dir[curD].x, c += dir[curD].y; // move forward
break;
}
}
if (allCleaned == true) {
int backD = ((d - 2) + 8) % 4;
if (grid[r + dir[backD].x][c + dir[backD].y] == WALL) {
notExit = false;
} else {
r += dir[backD].x, c += dir[backD].y;
}
}
}
printf("%d", retval);
return 0;
}
dir[]
: 문제에서 주어지는 방향에 따른 위치정보 기록grid[][]
: 맵의 상태를 기록, 3가지의 상태가 존재할 수 있음- Empty : 비어있는 칸, 청소 대상
- Wall : 벽
- Cleaned : 비어있지만 이미 청소를 진행한 칸