문제/백준

백준 2174번 로봇 시뮬레이션 [JAVA]

javaju 2021. 6. 25. 15:35

문제

가로 A(1≤A≤100), 세로 B(1≤B≤100) 크기의 땅이 있다. 이 땅 위에 로봇들이 N(1≤N≤100)개 있다.

로봇들의 초기 위치는 x좌표와 y좌표로 나타난다. 위의 그림에서 보듯 x좌표는 왼쪽부터, y좌표는 아래쪽부터 순서가 매겨진다. 또한 각 로봇은 맨 처음에 NWES 중 하나의 방향을 향해 서 있다. 초기에 서 있는 로봇들의 위치는 서로 다르다.

이러한 로봇들에 M(1≤M≤100)개의 명령을 내리려고 한다. 각각의 명령은 순차적으로 실행된다. 즉, 하나의 명령을 한 로봇에서 내렸으면, 그 명령이 완수될 때까지 그 로봇과 다른 모든 로봇에게 다른 명령을 내릴 수 없다. 각각의 로봇에 대해 수행하는 명령은 다음의 세 가지가 있다.

  1. L: 로봇이 향하고 있는 방향을 기준으로 왼쪽으로 90도 회전한다.
  2. R: 로봇이 향하고 있는 방향을 기준으로 오른쪽으로 90도 회전한다.
  3. F: 로봇이 향하고 있는 방향을 기준으로 앞으로 한 칸 움직인다.

간혹 로봇들에게 내리는 명령이 잘못될 수도 있기 때문에, 당신은 로봇들에게 명령을 내리기 전에 한 번 시뮬레이션을 해 보면서 안전성을 검증하려 한다. 이를 도와주는 프로그램을 작성하시오.

잘못된 명령에는 다음의 두 가지가 있을 수 있다.

  1. Robot X crashes into the wall: X번 로봇이 벽에 충돌하는 경우이다. 즉, 주어진 땅의 밖으로 벗어나는 경우가 된다.
  2. Robot X crashes into robot Y: X번 로봇이 움직이다가 Y번 로봇에 충돌하는 경우이다.

 

입력

첫째 줄에 두 정수 A, B가 주어진다. 다음 줄에는 두 정수 N, M이 주어진다. 다음 N개의 줄에는 각 로봇의 초기 위치(x, y좌표 순) 및 방향이 주어진다. 다음 M개의 줄에는 각 명령이 명령을 내리는 순서대로 주어진다. 각각의 명령은 명령을 내리는 로봇, 명령의 종류(위에 나와 있는), 명령의 반복 회수로 나타낸다. 각 명령의 반복 회수는 1이상 100이하이다.

 

 

출력

첫째 줄에 시뮬레이션 결과를 출력한다. 문제가 없는 경우에는 OK를, 그 외의 경우에는 위의 형식대로 출력을 한다. 만약 충돌이 여러 번 발생하는 경우에는 가장 먼저 발생하는 충돌을 출력하면 된다.

 

 

예제

 

풀이 방법

이 문제를 로봇들의 안정성을 검증하는 문제였습니다.

 

로봇이 수행할 수 있는 명령은 총 3가지로,

1) L : 로봇이 향하고 있는 방향을 기준으로 왼쪽으로 90도 회전

2) R : 로봇이 향하고 있는 방향을 기준으로 오른쪽으로 90도 회전

3) F : 로봇이 향하고 있는 방향을 기준으로 한 칸 이동 

 

먼저 로봇의 번호와 위치정보, 방향 정보를 list에 넣어두었습니다. 그리고 나서 M번의 명령을 통해 로봇들의 안정성을 검증할 수 있는데 move() 메서드를 이용해 움직일 로봇을 찾고, 명령에 따라 회전하거나 이동시켜 주었습니다. 만약 로봇이 움직였을 때,  그다음 움직일 위치가 벽에 충돌하는 경우 또는 다른 로봇과 충돌하는 경우에는 그 충돌을 출력해주고 종료해주었습니다. 반대로 로봇이 잘 움직였다면 그 마지막 위치의 정보를 다시 list에 넣어주고 다음 명령을 반복했습니다. M번의 로봇이 정상적으로 명령을 수행했다면 OK를 출력하고 종료해주었습니다.

코드

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
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
 
public class Main_BJ_2174_로봇시뮬레이션 {
    
    static class robot{
        int num ,x, y, dir;
 
        public robot(int num, int x, int y, int dir) {
            super();
            this.num = num;
            this.x = x;
            this.y = y;
            this.dir = dir;
        }
    }
    
    static int A,B,N,M;
    static int [][] map;
    static int [] dx = {-1,0,1,0};
    static int [] dy = {0,1,0,-1};
     
    static ArrayList<robot> list = new ArrayList<>();
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        
        st = new StringTokenizer(br.readLine());
        
        A = Integer.parseInt(st.nextToken()); //가로
        B = Integer.parseInt(st.nextToken()); //세로
        
        map = new int[B][A];
        
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken()); //로봇수 
        M = Integer.parseInt(st.nextToken()); // 명령수
        
        int num=0;
        for(int i=1;i<=N;i++) {
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken())-1;
            int y = Integer.parseInt(st.nextToken())-1;
            String dir = st.nextToken();
            
            map[B-y-1][x] = i;
            if(dir.equals("N")) num=0;
            else if(dir.equals("E")) num=1;
            else if(dir.equals("S")) num=2;
            else if(dir.equals("W")) num=3;
            
            list.add(new robot(i,B-y-1,x,num));
        }
        
        for(int i=0;i<M;i++) {
            st = new StringTokenizer(br.readLine());
            int robot = Integer.parseInt(st.nextToken());
            String command = st.nextToken();
            int repetition = Integer.parseInt(st.nextToken());
            move(robot,command,repetition);    
        }
        
        System.out.println("OK");
 
    }
    
    public static void move(int robot, String command, int repetition) {
        
        for(int i=0;i<list.size();i++) {
            if(list.get(i).num==robot) { //움직일 로봇 찾고
                int direction = list.get(i).dir;
                if(command.equals("L")) { //왼쪽으로 90도
                    for(int j=0;j<repetition;j++) {
                        if(direction==0) direction=3;
                        else direction--;
                    }
                    list.set(i, new robot(list.get(i).num,list.get(i).x,list.get(i).y,direction));
                }else if(command.equals("R")) { //오른쪽으로 90도
                    for(int j=0;j<repetition;j++) {
                        if(direction==3) direction=0;
                        else direction++;
                    }
                    list.set(i, new robot(list.get(i).num,list.get(i).x,list.get(i).y,direction));
                }else if(command.equals("F")) { //현재 방향에서 한칸 앞으로
                    int x = list.get(i).x;
                    int y = list.get(i).y;
                    map[x][y] = 0;
                    int nx=0, ny=0;
                    for(int j=0;j<repetition;j++) {
                        nx = x+dx[direction];
                        ny = y+dy[direction];
                        
                        if(range(nx,ny)) {
                            if(map[nx][ny]==0) {
                                x = nx; y = ny;
                            }else {
                                System.out.println("Robot "+list.get(i).num+" crashes into robot "+map[nx][ny]);
                                System.exit(0);
                            }
                        }else {
                            System.out.println("Robot "+list.get(i).num+" crashes into the wall");
                            System.exit(0);
                        }
                    }
                    map[nx][ny] = list.get(i).num;
                    list.set(i, new robot(list.get(i).num,nx,ny,direction));
                }
            }
        }
        
    }
    
    public static boolean range(int x, int y) {
        return x>=0 && x<&& y>=0 && y<A;
    }
 
}
cs