티스토리 뷰

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

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어

www.acmicpc.net

package CodingTestMemory.BJ.Simulation.P14503;

import java.io.*;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class P14503 {

    public static class Node {
        int x, y, dir;
        public Node(int x, int y, int dir) {
            this.x = x;
            this.y = y;
            this.dir = dir;
        }
    }

    static int N, M;
    static int cnt;
    static int[][] map;
    static boolean[][] visited;

    public static void func(int st_x, int st_y, int st_dir) {
        Queue<Node> queue = new LinkedList<>();
        queue.add(new Node(st_x, st_y, st_dir));
        while(!queue.isEmpty()) {
            Node e = queue.poll();
            if(!visited[e.y][e.x]) { // 아직 청소를 하지 않은 점이라면
                visited[e.y][e.x] = true; // 1. 현재 위치를 청소한다
                cnt++;
            }
            int flag = 0; // 네 방향 중에 청소할 부분이 있는지 유무 체크용
            int dir = e.dir; // 현재 바라보고 있는 방향
            for(int i = 0; i < 4; i++) { // 4방향을 모두 돌아본다
                int nx = e.x, ny = e.y;
                dir = (dir + 3) % 4; // 현재 바라보는 방향에서 왼쪽방향부터 탐색 (북->서->남->동)

                switch (dir) { // 방향 잡기
                    case 0: // 북
                        ny -= 1;
                        break;
                    case 1: // 동
                        nx += 1;
                        break;
                    case 2: // 남
                        ny += 1;
                        break;
                    default: // 서
                        nx -= 1;
                        break;
                }
                if(map[ny][nx] == 1 || visited[ny][nx]) { // 벽이거나, 이미 청소를 했다면
                    continue;
                }
                queue.add(new Node(nx, ny, dir));
                flag = 1; // 청소할 곳이 있다
                break;
            }
            if(flag == 0) { // 4방향 모두 청소할 곳이 없으면
                int nx = e.x, ny = e.y;
                switch (e.dir) { // 방향을 유지한 채로 한칸 후진
                    case 0: // 북(-> 남)
                        ny += 1;
                        break;
                    case 1: // 동(-> 서)
                        nx -= 1;
                        break;
                    case 2: // 남
                        ny -= 1;
                        break;
                    default: // 서
                        nx += 1;
                        break;
                }
                if(map[ny][nx] == 1) { // 후진할 곳이 벽이면
                    return;
                }
                queue.add(new Node(nx, ny, e.dir));
            }
        }
    }

    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 stk = new StringTokenizer(br.readLine());
        N = Integer.parseInt(stk.nextToken());
        M = Integer.parseInt(stk.nextToken());
        map = new int[N][M];
        visited = new boolean[N][M];

        stk = new StringTokenizer(br.readLine()); // 로봇청소기 출발 위치정보
        int start_y = Integer.parseInt(stk.nextToken());
        int start_x = Integer.parseInt(stk.nextToken());
        int start_dir = Integer.parseInt(stk.nextToken());

        for(int j = 0; j < N; j++) { // 지도 정보
            stk = new StringTokenizer(br.readLine());
            for(int i = 0; i < M; i++) {
                map[j][i] = Integer.parseInt(stk.nextToken());
            }
        }

        func(start_x, start_y, start_dir);

        bw.write(cnt + "\n");
        bw.flush();
        bw.close();
    }
}

시키는 대로만 고분고분 따라하면 여차저차 풀리기는 하는 문제였다.

 

앞으로 똑바로 갈것이지 괜히 왼쪽으로 돌고 후진하고 난리를 치는 청소기 때문에 골치를 좀 먹었지만 

그렇게 까다로운 문제는 아니었다.

 

방향을 잡고 왼쪽으로 회전하는것만 신경써주면 되는데

 

0 - 북

1 - 동

2 - 남

3 - 서

 

굳이 또 오른쪽으로 회전해주시는 출제자님 덕분에 다른 방식으로 방향을 잡아줘야 한다

(현재 방향 + 3) % 4 를 해주면 현재 바라보고 있는 방향에서 왼쪽을 바라볼 수 있게 값을 내준다.

 

 

다만 저 중복되는 switch 부분을 조금 깔끔하게 정리할 수 있을 것 같은데 싶은 아쉬움이 살짝 있는데,

또 굳이 큐가 없어도 될 것같긴 한데,, BFS 문제를 풀어보다 보니 자연스레 BFS꼴이 갖춰져버렸다

 

귀찮아서 못고치겠다. :D

 

'알고리즘 > 구현, 브루트포스' 카테고리의 다른 글

프로그래머스 | 자물쇠와 열쇠 - java  (0) 2022.08.28
[JAVA] # 14499 주사위 굴리기  (0) 2021.09.14
[JAVA] # 3190 뱀  (0) 2021.09.13
[JAVA] #14500 테트로미노  (0) 2021.08.23
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함