코테/백준

[백준/JAVA] 2174번: 로봇 청소기

imname1am 2024. 2. 7. 17:26
반응형

📖 문제

 

2174번: 로봇 시뮬레이션

첫째 줄에 두 정수 A, B가 주어진다. 다음 줄에는 두 정수 N, M이 주어진다. 다음 N개의 줄에는 각 로봇의 초기 위치(x, y좌표 순) 및 방향이 주어진다. 다음 M개의 줄에는 각 명령이 명령을 내리는 순

www.acmicpc.net

 

 

💡  풀이 방식

• 시뮬레이션

1. x좌표, y좌표를 입력받아 2차원 배열에서는 거꾸로 [y좌표][x좌표] 위치에 로봇 위치를 기록하고, 각 로봇의 위치와 방향은 로봇 객체 배열에 저장한다.

2. (명령 내리는 로봇, 명령 종류, 명령 반복 횟수)를 입력받아 명령을 수행한다.

 - 명령 종류가 L이거나 R인 경우, 입력받은 명령 반복 횟수만큼 방향을 전환해준다.

private static int getDir(int dir, char cmd) {
    if(cmd == 'L') {
        if(dir == 0) dir = 3;
        else         dir--;
    }
    else if(cmd == 'R') {
        if(dir == 3)    dir = 0;
        else            dir++;
    }

    return dir;
}

- 명령 종류가 F인 경우, 앞으로 한 칸 이동했을 때 격자 범위를 벗어난다면 부딪혔다는 메시지와 함께 종료한다. 격자 범위를 벗어나지 않았는데 해당 칸에 로봇이 있다면, 해당 칸에 있는 로봇과 충돌했다고 메시지를 출력하고 종료한다. 격자 범위를 벗어나지 않고, 해당 칸에 아무 것도 없다면, 로봇을 해당 칸으로 이동시킨다.

 

 

 

 

💥 유의사항

좌표를 거꾸로 줬으므로 북쪽으로 이동 시에는 y좌표가 증가하는 것이고, 남쪽으로 이동 시에는 y좌표가 감소하는 것이라고 생각하고 좌표를 dx/dy 배열을 설정해야 한다. 또한 로봇의 이동 가능 방향 순서는 N, E, S, W 이다.

 

 

 

🔺 코드

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
125
126
127
128
129
import java.util.*;
import java.io.*;
 
public class Main {
    static int[] dx = {010-1};   // 🔔 x좌표, y좌표 기준 북동남서 (0123)
    static int[] dy = {10-10};
    
    static int A, B, N, M;
    
    static int[][] map;
    static Robot[] robots;
    
    static boolean isError = false;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        
        A = Integer.parseInt(st.nextToken());   // 가로
        B = Integer.parseInt(st.nextToken());   // 세로
        
        map = new int[B + 1][A + 1];
        
        st = new StringTokenizer(br.readLine(), " ");
        N = Integer.parseInt(st.nextToken());   // 로봇 수
        M = Integer.parseInt(st.nextToken());   // 명령 수
 
        robots = new Robot[N + 1];
        
        int d = 0;
        for(int i = 1 ; i <= N ; i++) {
            st = new StringTokenizer(br.readLine(), " ");
            int x = Integer.parseInt(st.nextToken());   // x좌표
            int y = Integer.parseInt(st.nextToken());   // y좌표
            char dir = st.nextToken().charAt(0);        // 방향
            
            if(dir == 'N')       d = 0;
            else if(dir == 'E')  d = 1;
            else if(dir == 'S')  d = 2;
            else if(dir == 'W')  d = 3;
 
            map[y][x] = i;            
            robots[i] = new Robot(x, y, d);
        }
        
        // 명령 내리기
        while(M --> 0) {
            st = new StringTokenizer(br.readLine(), " ");
            int num = Integer.parseInt(st.nextToken());    // 명령 내리는 로봇
            char cmd = st.nextToken().charAt(0);           // 명령 종류
            int repeat = Integer.parseInt(st.nextToken()); // 명령 반복 횟수
            
            move(num, cmd, repeat);
            
            if(isError) {
                break;
            }
        }
        
        if(!isTrue)
            System.out.println("OK");   
    }
    
    private static void move(int num, char cmd, int repeat) {
        while(repeat --> 0) {
            int x = robots[num].x;
            int y = robots[num].y;
            int d = robots[num].dir;
            
            if(cmd == 'L' || cmd == 'R') {
                int nd = getDir(d, cmd);
                robots[num].dir = nd;
            }
            else if(cmd == 'F') {
                int nx = x + dx[d];
                int ny = y + dy[d];
                
                if(!inRange(ny, nx)) {
                    System.out.println("Robot " + num + " crashes into the wall");
                   isError = true;
                    return;
                }
                
                if(map[ny][nx] != 0) {
                    System.out.println("Robot " + num + " crashes into robot " + map[ny][nx]);
                   isError = true;
                    return;
                }
                else {
                    map[y][x] = 0; // 현재 칸 로봇 제거하고, 다음 칸으로 로봇 이동하기
                    map[ny][nx] = num;
                    
                    robots[num].x = nx; // 좌표 변경하기
                    robots[num].y = ny;
                }
            }       
        }
    }
    
    // 🔔 방향 전환 메소드
    private static int getDir(int dir, char cmd) {
        if(cmd == 'L') {
            if(dir == 0) dir = 3;
            else         dir--;
        }
        else if(cmd == 'R') {
            if(dir == 3)    dir = 0;
            else            dir++;
        }
        
        return dir;
    }
    
    // 🔔 격자 범위 내에 들어오는지 확인하는 메소드
    private static boolean inRange(int y, int x) {
        return (1 <= x && x <= B && 1 <= y && y <= A);
    }
}
 
class Robot {
    int x, y, dir;
    
    public Robot(int x, int y, int dir) {
        this.x = x;
        this.y = y;
        this.dir = dir;
    }
}
 
cs

 

 

 


💦 어려웠던 점

- 좌표를 거꾸로 줘서 dx/dy 배열도 어떻게 해야할지, 격자 내 범위도 제대로 작성했는지 헷갈렸다..

- 방향 전환 메소드 작성할 생각할 때 HashMap에 각각 저장하고 뽑아 쓸 생각을 했는데 그럴 필요 없이 저렇게 dx/dy배열에 회전 순서대로만 저장해 활용해도 되는 것이었다.

 

 

🧐 새로 알게 된 내용

좌표를 거꾸로 줄 때는 [row][col]이 아닌 [col][row] 이렇게 값을 입력받아 사용한다..

이렇게 좌표 뒤집는 문제를 여러 개 더 풀어봐야겠다.

 

 

1회독 2회독 3회독 4회독 5회독
V        

(참고)

 

#백준_2174 로봇 시뮬레이션 - Java 자바

# 유형 : 시뮬레이션, 구현 # 난이도는 골드 4인데 어렵지 않은 문제였다. 좌표를 거꾸로 줬기 때문에 그거만 생각하여 북쪽으로 이동할때는 y좌표가 감소하는것이 아닌 증가, 남쪽으로 이동할 때

ukyonge.tistory.com

 

반응형