해버니 2023. 11. 26. 11:49
반응형

 

 

문제

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

 

2174번: 로봇 시뮬레이션

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

www.acmicpc.net

 

 

 

 

 

 

엄청 어렵진 않은 구현문제를 짝지에게 소개받아 풀게 되었다.

 

 

 

 

 

 

 

 

풀이

지도(이차원 배열)에 로봇이 있는 위치를 1 없는 위치를 0으로 잡고, 1이라면 로봇의 num을 검색하는 로직을 짰다.

하지만 1과 0으로 하지 않고, 0과 로봇넘버 숫자들로 넣었다면 로봇의 num을 검색하는 로직을 짜지 않아도 되지 않았을까? 더 간단해지지 않았을까? 하는 아쉬움이 있었다. 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

public class Main {
    public static Set<Robot> robot = new HashSet<>();

    public static class Robot {
        int num;
        int x;
        int y;
        String way;

        public Robot(int num, int x, int y, String way) {
            super();
            this.num = num;
            this.x = x;
            this.y = y;
            this.way = way;
        }
    }

    /**
     * 반환값이 0이면 OK, 1이상이면 충돌, 1 이상은 로봇의 번호임
     * 
     * @param robotNum
     * @param way
     * @param length
     * @return
     */
    public static int[] move(int robotNum, String way, int length, int[][] field) {
        Robot targetRobot = findRobotByNum(robotNum);
        int[] answer = new int[2]; // 0 : 충돌한 로봇의 넘버, 1: 충돌당한 로봇의 넘버

        if (targetRobot != null) {
            int x = targetRobot.x;
            int y = targetRobot.y;

            // way가 F면 이동, 다른거면 회전임
            if (way.equals("F")) {
                switch (targetRobot.way) {
                    case "N": // y ++
                        // 다른 로봇과 부딪히는지
                        for (int i = 0; i < length; i++) {
                            field[x][y] = 0;
                            // 벽에 부딪히는지
                            if (field[0].length <= (y + 1)) {
                                answer[0] = targetRobot.num;
                                return answer;
                            }

                            if (field[x][y + 1] == 1) {
                                Robot crushedRobot = findCrushedRobotByNum(x, (y + 1));
                                if (crushedRobot != null) {
                                    answer[0] = targetRobot.num;
                                    answer[1] = crushedRobot.num;
                                }

                                return answer;
                            } else {
                                field[x][y + 1] = 1;
                                y++;
                                targetRobot.y++;
                            }
                        }
                        break;
                    case "W": // x --
                        // 다른 로봇과 부딪히는지
                        for (int i = 0; i < length; i++) {
                            field[x][y] = 0;
                            // 벽에 부딪히는지
                            if ((x - 1) < 0) {
                                answer[0] = targetRobot.num;
                                return answer;
                            }

                            if (field[x - 1][y] == 1) {
                                Robot crushedRobot = findCrushedRobotByNum((x - 1), y);
                                if (crushedRobot != null) {
                                    answer[0] = targetRobot.num;
                                    answer[1] = crushedRobot.num;
                                }
                                return answer;
                            } else {
                                field[x - 1][y] = 1;
                                x--;
                                targetRobot.x--;
                            }
                        }
                        break;
                    case "E": // x ++
                        // 다른 로봇과 부딪히는지
                        for (int i = 0; i < length; i++) {
                            field[x][y] = 0;
                            // 벽에 부딪히는지
                            if (field.length <= (x + 1)) {
                                answer[0] = targetRobot.num;
                                return answer;
                            }

                            if (field[x + 1][y] == 1) {
                                Robot crushedRobot = findCrushedRobotByNum((x + 1), y);
                                if (crushedRobot != null) {
                                    answer[0] = targetRobot.num;
                                    answer[1] = crushedRobot.num;
                                }
                                return answer;
                            } else {
                                field[x + 1][y] = 1;
                                x++;
                                targetRobot.x++;
                            }
                        }
                        break;
                    case "S": // y--
                        // 다른 로봇과 부딪히는지
                        for (int i = 0; i < length; i++) {
                            field[x][y] = 0;
                            // 벽에 부딪히는지
                            if ((y - 1) < 0) {
                                answer[0] = targetRobot.num;
                                return answer;
                            }

                            if (field[x][y - 1] == 1) {
                                Robot crushedRobot = findCrushedRobotByNum(x, (y - 1));
                                if (crushedRobot != null) {
                                    answer[0] = targetRobot.num;
                                    answer[1] = crushedRobot.num;
                                }
                                return answer;
                            } else {
                                field[x][y - 1] = 1;
                                y--;
                                targetRobot.y--;
                            }
                        }
                        break;
                }
                // System.out.println("이동한 위치 : x :" + x + " y :" + y);
            } else {
                for (int i = 0; i < length % 4; i++) {
                    String currentWay2 = targetRobot.way;
                    String findWayValue = findWay(currentWay2, way);
                    if (!findWayValue.equals("")) {
                        targetRobot.way = findWayValue;
                    }
                    // System.out.println(targetRobot.way);
                }
            }

        }

        return answer;
    }

    /**
     * num으로 로봇 찾기
     * 
     * @param num
     * @return
     */
    public static Robot findRobotByNum(int num) {
        for (Robot r : robot) {
            if (r.num == num) {
                return r;
            }
        }
        return null;
    }

    /**
     * 좌표로 로봇 찾기
     * 
     * @param x
     * @param y
     * @return
     */
    public static Robot findCrushedRobotByNum(int x, int y) {
        for (Robot r : robot) {
            if (r.x == x && r.y == y) {
                return r;
            }
        }
        return null;
    }


    /**
     * 방향 정하기
     * 
     * @param currentWay
     * @param changeWay
     * @return
     */
    public static String findWay(String currentWay, String changeWay) {
        switch (currentWay) {
            case "N":
                switch (changeWay) {
                    case "L":
                        return "W";
                    case "R":
                        return "E";
                }
                break;
            case "W":
                switch (changeWay) {
                    case "L":
                        return "S";
                    case "R":
                        return "N";
                }
                break;
            case "E":
                switch (changeWay) {
                    case "L":
                        return "N";
                    case "R":
                        return "S";
                }
                break;
            case "S":
                switch (changeWay) {
                    case "L":
                        return "E";
                    case "R":
                        return "W";
                }
                break;
        }
        return "";
    }


    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        StringTokenizer st = new StringTokenizer(br.readLine());
        int a = Integer.parseInt(st.nextToken());
        int b = Integer.parseInt(st.nextToken());
        int[][] field = new int[a][b];

        st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());

        for (int i = 1; i <= n; i++) {
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            String way = st.nextToken();
            field[x - 1][y - 1] = 1;
            Robot r = new Robot(i, (x - 1), (y - 1), way);
            robot.add(r); // 로봇의 개수만큼 추가
        }


        int[] answer = new int[2];
        for (int i = 0; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            int robotNum = Integer.parseInt(st.nextToken());
            String way = st.nextToken();
            int length = Integer.parseInt(st.nextToken());

            answer = move(robotNum, way, length, field);

            if (answer[0] != 0 && answer[1] == 0) {
                bw.write("Robot " + String.valueOf(answer[0]) + " crashes into the wall\n");
                break;
            } else if (answer[1] != 0) {
                bw.write("Robot " + String.valueOf(answer[0]) + " crashes into robot " + String.valueOf(answer[1]) + "\n");
                break;
            }

        }
           
        if (answer[0] == 0 && answer[1] == 0) {
            bw.write("OK\n");
        }


        bw.flush();
        bw.close();
    }
}

아웅 길다 길어

 

 

 

 

 

 

 

 

 

암튼 코드 구현을 하고 예제 입력도 알맞게 출력이 돼서 제출을 했는데, 틀렸습니다라고 떴다.

이럴때 화나죠,, 어디가 어떻게 틀렸는지 모르니까,,

 

하지만 광기어린 분께서 테스트 케이스를 많이 올려주신 덕분에 밑 테스트 케이스로 틀린 부분을 바로잡을 수 있었다.

29 44
52 10
28 29 E
25 31 S
22 31 N
5 2 E
16 28 E
19 2 W
5 4 S
22 38 S
6 37 E
2 25 N
17 19 N
4 6 S
8 25 N
13 22 N
4 11 N
5 39 S
18 34 S
17 1 W
11 17 N
14 34 W
13 31 W
26 1 S
12 38 E
14 21 W
2 2 S
23 20 S
24 14 S
5 29 E
2 10 W
26 24 W
24 34 N
17 38 E
17 29 N
20 26 S
10 7 N
19 8 N
27 7 W
5 5 W
4 39 S
27 32 S
25 12 S
28 25 S
18 31 W
15 41 S
20 20 E
6 22 W
9 12 W
24 2 E
19 32 N
23 34 S
17 11 W
6 4 S
46 L 2
43 F 4
47 F 2
33 F 5
36 L 11
3 L 2
45 L 2
40 F 5
33 F 10
45 F 6
27 37
46 100
20 22 S
26 3 N
22 28 S
17 16 W
15 18 N
11 17 S
7 15 W
17 2 E
7 16 W
13 14 S
11 27 N
21 23 S
11 12 E
22 11 S
19 11 E
22 1 S
8 16 S
21 18 S
2 20 W
16 6 S
5 22 N
3 15 S
2 29 W
14 23 S
19 9 W
12 30 N
3 28 N
23 33 S
25 24 N
6 4 S
12 6 N
1 14 N
24 1 E
8 21 W
23 22 W
10 21 N
17 31 S
7 11 S
13 7 E
6 27 S
3 6 W
12 35 E
23 16 E
5 29 W
20 23 S
1 22 E
3 L 2
25 R 25
33 R 5
24 F 9
25 F 2
15 F 2
46 L 4
46 L 13
45 L 14
26 F 4
4 F 5
42 F 1
39 R 3
24 L 2
6 F 2
46 F 5
12 F 8
6 F 3
9 F 5
36 F 5
38 R 2
35 L 30
38 F 7
2 R 6
46 L 3
21 R 2
44 F 1
36 F 2
23 F 1
40 R 30
11 F 3
20 L 6
10 F 6
10 R 20
11 F 1
35 L 29
27 F 8
3 L 24
14 L 6
32 F 10
40 F 8
26 R 3
12 F 5
10 L 19
10 L 2
36 R 2
27 F 1
21 L 2
39 F 1
17 F 7
46 L 25
2 L 13
5 R 2
2 R 18
22 F 9
45 L 18
16 F 6
5 F 9
34 F 1
5 L 2
21 F 6
36 L 26
41 F 6
2 F 1
5 F 8
38 F 5
35 F 9
15 R 2
31 F 2
37 L 2
44 F 2
46 F 1
40 F 1
42 F 4
12 F 9
22 F 2
7 R 2
9 R 24
17 F 6
15 R 2
34 F 5
46 F 6
29 R 2
9 F 10
34 R 11
15 L 10
16 F 7
8 R 22
1 F 8
38 F 3
41 F 5
22 L 7
45 R 2
2 F 5
20 F 3
24 L 1
32 L 2
43 F 6
38 F 2
32 F 6
# Robot 33 crashes into robot 32

 

 

 

 

 

 

 

 

 

 

정답 

 

 

 

 

 

 

반응형