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

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 벽 또는 빈 칸이다. 청소기는 바라보는 방향이 있으며, 이 방향은 동, 서, 남, 북중 하나이다. 지도의 각 칸은 (r, c)로 나타낼 수 있고, r은 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로 부터 떨어진 칸의 개수이다. 로봇 청소기는 다음

www.acmicpc.net

문제에 나와있는 대로 차근차근 구현해주면 되는 시뮬레이션 문제이다.

이 문제에는 방향 전환만 주의해주면 쉽게 해결할 수 있다.

 

처음에 벽이랑 범위 벗어난 거랑 구분해야 하는 줄 알고 고생할뻔했는데 문제를 자세히 보면 모든 외곽은 벽으로 되어있기 때문에 범위 체크를 따로 해주지 않아도 된다.

 

문제에서 0인 경우에는 북쪽/ 1인 경우에는 동쪽/ 2인 경우에는 남쪽/ 3인 경우에는 서쪽이라고 주어졌으므로

그에 맞게 다음과 같이 방향 배열을 잘 저장해놓는다.

 

dx[] = { -1,0,1,0 }

dy[] = { 0,1,0,-1 }

 

청소를 하기 위해 왼쪽 방향을 보기 위해서는 (현재 방향 + 3)%4를 해주면 왼쪽 방향 index로 올 수 있다.

즉, 현재 동쪽(1)을 바라보고 있는 상황에서는 왼쪽 방향은 북쪽(0)인데 (1+3)%4 == 0으로 북쪽을 바라보게 된다.

 

후진을 하는 경우에는 북쪽을 바라보고 있었다면 남쪽 방향으로, 남쪽을 바라보고 있었다면 북쪽으로 이동하면 된다.

마찬가지로 동에서 서, 서에서 동으로 이동해주면 된다.

즉, 0에서 2, 2에서 0, 1에서 3, 3에서 1 이므로 위와 비슷하게 (현재 방향+2)%4를 해주면 된다.

 

 

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 <iostream>
using namespace std;
 
int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };
int n, m;
int map[50][50];
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
 
    cin >> n >> m;
 
    int r, c, dir;
    cin >> r >> c >> dir;
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> map[i][j];
        }
    }
 
    int cnt = 0;
    while (true) {
        //현재 위치 청소
        if (map[r][c] == 0) {
            map[r][c] = 2;
            cnt++;
        }
 
 
        //네 방향 모두 청소가 이미 되어있거나 벽인 경우
        if (map[r - 1][c] != 0 && map[r + 1][c] != 0 && map[r][c - 1!= 0 && map[r][c + 1!= 0) {
            
            //후진
            r += dx[(dir + 2) % 4];
            c += dy[(dir + 2) % 4];
 
            //뒤쪽 방향이 벽이라 후진도 할 수 없는 경우
            if (map[r][c] == 1) {
                //작동 중지
                break;
            }
            else {
                continue;
            }
        }
 
 
        //현재 방향의 왼쪽 방향
        dir = (dir + 3) % 4;
 
        //왼쪽 방향에 청소하지 않은 공간이 존재한다.
        if (map[r + dx[dir]][c + dy[dir]] == 0) {
            //해당방향으로 전진
            r += dx[dir];
            c += dy[dir];
        }
        else {
            continue;
        }
 
 
    }
 
    cout << cnt << '\n';
 
 
    return 0;
}
Colored by Color Scripter
 

'BOJ' 카테고리의 다른 글

[BOJ] 14500. 테트로미노  (0) 2019.08.04
[BOJ] 14499. 주사위 굴리기  (0) 2019.08.04
[BOJ] 14502. 연구소  (0) 2019.08.04
[BOJ] 15685. 드래곤 커브  (0) 2019.08.04
[BOJ] 15686. 치킨 배달  (0) 2019.08.04

+ Recent posts