백준 로봇 청소기 14503 java

정상민·2023년 8월 3일

문제링크

문제 접근

  • 문제에서 주어진 각 단계를 메소드화
  • 좌표에 관한 설명이 있는데 결국 0부터 시작한다는 뜻
  • 맵 테두리에는 벽이 있어서 범위 밖으로 나갈 일 없음

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class baek_14503 {
    static int[] di = {-1,0,1,0};
    static int[] dj = {0,1,0,-1};
    static int[][] map; // 맵
    static boolean[][] clean; // 청소유무
    static int N,M, si,sj, sd, cnt;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());
        si = Integer.parseInt(st.nextToken());
        sj = Integer.parseInt(st.nextToken());
        sd = Integer.parseInt(st.nextToken());
        map = new int[N][M];
        clean = new boolean[N][M];
        for(int i=0;i<N;i++){
            st = new StringTokenizer(br.readLine());
            for(int j=0;j<M;j++){
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        while(true){
            if(step1() == 2){ // 1단계 실행 후 결과에 따라 2단계 또는 3단계 실행
                if(step2() == 4) break; // 2단계 결과에 따라 종료 여부
            }
            else{
                step3(); // 3단계 실시 후 다시 1단계
            }
        }
        System.out.println(cnt);
    }
    private static int step1(){
        if(!clean[si][sj]) {
            clean[si][sj] = true;
            cnt++;
        }
        for(int d=0;d<4;d++){
            int nexti = si + di[d];
            int nextj = sj + dj[d];
            if(map[nexti][nextj] == 0 && !clean[nexti][nextj]) return 3;
        }
        return 2;
    }
    private static int step2(){
        int nexti = si + di[(sd+2) % 4];
        int nextj = sj + dj[(sd+2) % 4];
        if(map[nexti][nextj] == 1) return 4;
        si = nexti;
        sj = nextj;
        return 1;
    }
    private static void step3(){
        sd = sd - 1;
        if(sd == -1) sd = 3;
        int nexti = si + di[sd];
        int nextj = sj + dj[sd];
        if(map[nexti][nextj] == 0 && !clean[nexti][nextj]){
            si = nexti;
            sj = nextj;
        }
    }
}

결과

정리

  • 문제 잘 읽으면서 청소유무랑 벽 헷갈리지 않고 체크해서 한번에 성공
  • 후진하는 것은 방향 바꾸는 것 아님
  • 재귀로 해야하나 싶었지만 while문 안에서 각 단계 리턴값으로 처리하는 것이 더 직관적
  • 후진하는 방향은 (d-2) % 4 , 반시계 회전은 -1(음수되면 3으로)
profile
안녕하세요! 개인 공부를 꾸준히 기록하는 공간입니다.

1개의 댓글

comment-user-thumbnail
2023년 8월 3일

많은 도움이 되었습니다, 감사합니다.

답글 달기