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

 

2174번: 로봇 시뮬레이션

문제 가로 A(1≤A≤100), 세로 B(1≤B≤100) 크기의 땅이 있다. 이 땅 위에 로봇들이 N(1≤N≤100)개 있다. 로봇들의 초기 위치는 x좌표와 y좌표로 나타난다. 위의 그림에서 보듯 x좌표는 왼쪽부터, y좌표는 아래쪽부터 순서가 매겨진다. 또한 각 로봇은 맨 처음에 NWES 중 하나의 방향을 향해 서 있다. 초기에 서 있는 로봇들의 위치는 서로 다르다. 이러한 로봇들에 M(1≤M≤100)개의 명령을 내리려고 한다. 각각의 명령은 순차적으로

www.acmicpc.net

이 문제의 정답률이 낮은 것은 방향이 헷갈려서인 것 같다. 우선 1번 인덱스가 왼쪽 아래부터 시작하고, 입력받는 x, y 도 반대이다. 문제에서 주어지는 아래 그림에서 오른쪽 위에 있는 로봇의 좌표는 (5, 4)인 것에 주의해야 한다.

 

 

 

 

 

 

위의 그림을 아래 그림처럼 시계방향으로 90도 돌려서 생각하면 쉽게 풀 수 있다. (x <= A, y <= B)

일반적으로 사용하는 2차원 배열의 모양이므로 (x, y)를 입력받은 그대로 사용할 수 있다.

대신에 방향도 같이 90도 돌려야 하므로 W면 N방향으로/ N이면 E방향으로/ E면 S방향으로/ S면 W방향으로 바꿔준다.

 

로봇 정보는 현재 위치정보와 방향 정보를 구조체에 넣어서 관리한다. 로봇들은 처음에 입력받은 순서대로 번호를 가지므로 로봇 정보를 가지는 구조체를 벡터에 순차적으로 넣어놓는다. 벡터의 i번 인덱스 위치에 들어있는 로봇 정보가 i번 로봇의 정보이다. 1번 로봇부터 사용하기 위해 벡터에 0번 인덱스 위치에 아무 값을 넣어주고 시작하였다.

 

 

로봇이 이동하는 위치에 다른 로봇에 이미 있는지 검사하기 위해 2차원 int 배열에 로봇의 번호를 저장해놓는다.

배열의 (x, y)에 있는 로봇의 번호를 저장하고, 로봇이 없다면 초기값인 0이다.

예를 들어 로봇 2번이 (5, 4)에 있다면  check[5][4] = 2 이다.

이동후에는 기존 위치의 값을 다시 0으로 만들어주고 새로 이동한 곳에 로봇 번호를 다시 저장한다.

 

 

이후에는 입력받은 로봇 번호, 명령, 반복 횟수를 이용하여 시뮬레이션해주면 된다. 벽에 부딪히거나 다른 로봇에 부딪히는 경우는 F명령으로 이동했을 때만 발생하므로 F명령일 때만 검사해주면 된다.

 

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
#include <iostream>
#include <vector>
using namespace std;
 
int A, B, N, M;
 
int check[102][102];
 
//북, 동, 남, 서
int dx[] = { -1,0,1,0 };
int dy[] = { 0,1,0,-1 };
 
struct Robot {
    int x;
    int y;
    int dir;
    Robot(int a, int b, int c) {
        x = a;
        y = b;
        dir = c;
    }
};
 
vector<Robot> vt;
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
 
    cin >> A >> B;
    cin >> N >> M;
 
    int x, y, dir;
    char d;
 
    //index 1부터 시작하기위해 아무 값 넣어줌
    vt.push_back(Robot(-1-1-1));
 
    for (int i = 1; i <= N; i++) {
        cin >> x >> y >> d;
 
        if (d == 'N'//N을 입력받으면 E방향으로 설정.
            dir = 1;
        else if (d == 'E'//E면 S방향으로 설정.
            dir = 2;
        else if (d == 'S'//S면 W방향으로 설정.
            dir = 3;
        else
            dir = 0//W면 N방향으로 설정
 
        vt.push_back(Robot(x, y, dir));
        check[x][y] = i;
    }
 
 
    int num;
    char order;
    int orderCnt;
 
    int crashWall = 0//벽에 부딪힌 로봇 번호를 저장
    int lastRobot = 0//다른 로봇에 부딪힌 현재 이동 로봇을 저장
    int crashRobot = 0//현재 이동중인 로봇이 부딪힌 다른 로봇의 번호를 저장
 
 
    while (M--) {
        cin >> num >> order >> orderCnt;
 
        //잘못된 명령이 발생해서 벽이나 로봇이 부딪힌 경우 넘어가서 입력만 계속 받는다.
        if (crashWall || crashRobot) continue;
 
        x = vt[num].x;
        y = vt[num].y;
        dir = vt[num].dir;
 
        //명령 반복 횟수만큼 반복
        while (orderCnt--) {
            if (order == 'L') {
                //왼쪽 90도 회전
                dir = (dir + 3) % 4;
                vt[num].dir = dir;
            }
            else if (order == 'R') {
                //오른쪽 90도 회전
                dir = (dir + 1) % 4;
                vt[num].dir = dir;
            }
            else if (order == 'F') {
                
                //이전 위치 비워준다.
                check[x][y] = 0;
 
                x = x + dx[dir];
                y = y + dy[dir];
 
                if (x < 1 || y < 1 || x > A || y > B) {
                    //벽에 부딪힘
                    crashWall = num;
                    break;
                }
                else if (check[x][y] != 0) {
                    //로봇에 부딪힘
                    lastRobot = num;
                    crashRobot = check[x][y];
                    break;
                }
                else {
                    //이동
                    vt[num].x = x;
                    vt[num].y = y;
                    check[x][y] = num;
                }
            }
 
        }
    }
 
 
    if (crashWall) cout << "Robot " << crashWall << " crashes into the wall" << '\n';
    else if (crashRobot) cout << "Robot " << lastRobot << " crashes into robot " << crashRobot << '\n';
    else cout << "OK" << '\n';
 
 
    return 0;
}
Colored by Color Scripter
 

'BOJ' 카테고리의 다른 글

[BOJ] 17090. 미로 탈출하기  (0) 2020.05.01
[BOJ] 16401. 과자 나눠주기  (2) 2020.04.29
[BOJ] 10711. 모래성  (0) 2020.04.27
[BOJ] 2866. 문자열 잘라내기  (0) 2020.04.21
[BOJ] 5427. 불  (0) 2020.04.19

+ Recent posts