Notice
Recent Posts
Recent Comments
Link
«   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
Archives
Today
Total
관리 메뉴

최's 먹공로그

BOJ14503 로봇청소기 본문

APS

BOJ14503 로봇청소기

ChoiSH313 2022. 6. 26. 18:07

<Solution>

1. 현재 위치 청소 -> visited = true

2. 현재 위치에서 바로 왼쪽 청소가능? - 방향 바꾸기 , 한 칸 전진 후 다시 (1)번 진행

3. 현재 위치에서 바로 왼쪽 청소불가능? - 방향만 바꾸기 후 다시 (2)번 진행

4. 4 방향 모두 확인 했을 때 청소 불가능? - 그 때의 방향에서 한 칸 후진 후 다시 (2)번 진행

5. 후진도 불가능? - 종료

6. visited에 있는 true의 개수가 로봇 청소기가 청소한 공간임

first() : 현재 위치를 청소하는 함수

second() : (1) 현재방향과 현재위치에서 4 방향 모두 청소가 가능한지 검사

  (2) 현재방향과 현재위치를 기준으로 바로 왼쪽이 청소가 가능하면 방향과 위치 갱신 다시 first()로

  (3) 바로 왼쪽이 청소가 불가능하면 방향만 바꾸고 다시 second()로

third() : (1) 현재방향과 현재위치에서 후진가능한지 확인

     (2) 가능하면 후진 후 다시 second()로

     (3) 불가능하면 모든 함수 끝낼 수 있게 flag변경해주고 종료

 

<Source Code>

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
public class Main {
 
    private static int[][] map;
    private static boolean[][] visited;
    private static int N;
    private static int M;
    private static int robot_r;
    private static int robot_c;
    private static int robot_dir;
    private static boolean world_flag;
    private static boolean[] dir_check;
 
    public static void main(String[] args) throws Exception {
 
        // input
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine().trim(), " ");
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        map = new int[N][M];
        visited = new boolean[N][M];
        dir_check = new boolean[4]; // 이동했을 때만 초기화
        st = new StringTokenizer(br.readLine().trim(), " ");
        robot_r = Integer.parseInt(st.nextToken());
        robot_c = Integer.parseInt(st.nextToken());
        robot_dir = Integer.parseInt(st.nextToken());
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine().trim(), " ");
            for (int j = 0; j < M; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
 
        // start
        world_flag = false;
        while (!world_flag) {
            // 1. 현재 위치 청소
            first();
        }
        int cnt = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if(visited[i][j])
                    cnt++;
            }
        }
        System.out.println(cnt);
    }
 
    private static void first() {
        // visited 체크만
        dir_check = new boolean[4];
        visited[robot_r][robot_c] = true;
        second();
        if(world_flag)
            return;
    }
 
    private static int[] dr = {-1,0,1,0};
    private static int[] dc = {0,1,0,-1};
    
    private static void second() {
        // 현재방향과 현재위치에서 네 방향이 모두 청소 불가능한 곳이면 third로
        boolean flag = false;
        for (int i = 0; i < 4; i++) {
            int nr = robot_r + dr[i];
            int nc = robot_c + dc[i];
            if(nr>=0 && nr<N && nc>=0 && nc<M) {
                if(map[nr][nc] == 0 && !visited[nr][nc])
                    flag = true;
            }
        }
        if(!flag) {
            third();
            if(world_flag)
                return;
        }
        // 로봇의 현재 위치와 방향을 기준으로 왼쪽 청소가능한지 체크
        if (robot_dir == 0) {
            int robot_nr = robot_r;
            int robot_nc = robot_c - 1;
            // 현재방향과 위치를 기준으로 왼쪽이 청소 가능한 곳이다
            if(robot_nc >= 0 && map[robot_nr][robot_nc] == 0 && !visited[robot_nr][robot_nc]) {
                robot_r = robot_nr;
                robot_c = robot_nc;
                robot_dir = 3;
                first();
            }
            // 현재방향과 위치를 기준으로 왼쪽이 청소 불가능한 곳이다
            else if(robot_nc >= 0 && (map[robot_nr][robot_nc] == 1 || visited[robot_nr][robot_nc])){
                robot_dir = 3;
                second();
            }
        } else if (robot_dir == 1) {
            int robot_nr = robot_r - 1;
            int robot_nc = robot_c;
            if(robot_nr >= 0 && map[robot_nr][robot_nc] == 0 && !visited[robot_nr][robot_nc]) {
                robot_r = robot_nr;
                robot_c = robot_nc;
                robot_dir = 0;
                first();
            }
            else {
                robot_dir = 0;
                second();
            }
        } else if (robot_dir == 2) {
            int robot_nr = robot_r;
            int robot_nc = robot_c + 1;
            if(robot_nc < M && map[robot_nr][robot_nc] == 0 && !visited[robot_nr][robot_nc]) {
                robot_r = robot_nr;
                robot_c = robot_nc;
                robot_dir = 1;
                first();
            }
            else {
                robot_dir = 1;
                second();
            }
        } else if (robot_dir == 3) {
            int robot_nr = robot_r + 1;
            int robot_nc = robot_c ;
            if(robot_nr < N && map[robot_nr][robot_nc] == 0 && !visited[robot_nr][robot_nc]) {
                robot_r = robot_nr;
                robot_c = robot_nc;
                robot_dir = 2;
                first();
            }
            else {
                robot_dir = 2;
                second();
            }
        }
    }
 
    private static void third() {
        // 현재방향에서 후진
        if(robot_dir == 0) {
            int robot_nr = robot_r + 1;
            // 후진가능
            if(robot_nr < N && map[robot_nr][robot_c] == 0) {
                robot_r = robot_nr;
                second();
            }
            else if(map[robot_nr][robot_c] == 1){
                world_flag = true;
                return;
            }
        } else if(robot_dir == 1) {
            int robot_nc = robot_c - 1;
            if(robot_nc >= 0 && map[robot_r][robot_nc] == 0) {
                robot_c = robot_nc;
                second();
            }
            else if(map[robot_r][robot_nc] == 1){
                world_flag = true;
                return;
            }
        } else if(robot_dir == 2) {
            int robot_nr = robot_r - 1;
            // 후진가능
            if(robot_nr >= 0 && map[robot_nr][robot_c] == 0) {
                robot_r = robot_nr;
                second();
            }
            else if(map[robot_nr][robot_c] == 1){
                world_flag = true;
                return;
            }
        } else if(robot_dir == 3) {
            int robot_nc = robot_c + 1;
            if(robot_nc < M && map[robot_r][robot_nc] == 0) {
                robot_c = robot_nc;
                second();
            }
            else if(map[robot_r][robot_nc] == 1){
                world_flag = true;
                return;
            }
        }
    }
}

'APS' 카테고리의 다른 글

BOJ18809 Gaaaaaaarden  (1) 2022.10.08
BOJ17779 게리맨더링2  (0) 2022.07.24
BOJ9205 맥주 마시면서 걸어가기  (0) 2022.06.26
BOJ2573 빙산  (0) 2022.06.26
BOJ2468 안전영역  (0) 2022.06.13