알고리즘/탐색

[백준] 14503 로봇 청소기 (DFS) - Java

2023. 5. 17. 16:07
목차
  1. 접근법
  2. 문제 풀이

 

 

14503번: 로봇 청소기

첫째 줄에 방의 크기 $N$과 $M$이 입력된다. $(3 \le N, M \le 50)$  둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 $(r, c)$와 처음에 로봇 청소기가 바라보는 방향 $d$가 입력된다. $d$가 $0$인 경우 북쪽

www.acmicpc.net

 

문제 상황

로봇 청소기와 방의 상태가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오.

로봇 청소기가 있는 방은 $N \times M$ 크기의 직사각형으로 나타낼 수 있으며, $1 \times 1$ 크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 벽 또는 빈 칸이다. 청소기는 바라보는 방향이 있으며, 이 방향은 동, 서, 남, 북 중 하나이다. 방의 각 칸은 좌표 $(r, c)$로 나타낼 수 있고, 가장 북쪽 줄의 가장 서쪽 칸의 좌표가 $(0, 0)$, 가장 남쪽 줄의 가장 동쪽 칸의 좌표가 $(N-1, M-1)$이다. 즉, 좌표 $(r, c)$는 북쪽에서 $(r+1)$번째에 있는 줄의 서쪽에서 $(c+1)$번째 칸을 가리킨다. 처음에 빈 칸은 전부 청소되지 않은 상태이다.

로봇 청소기는 다음과 같이 작동한다.

  1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
  2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
    1. 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
    2. 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
  3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
    1. 반시계 방향으로 $90^\circ$ 회전한다.
    2. 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
    3. 1번으로 돌아간다.

 

입력

첫째 줄에 방의 크기 $N$과 $M$이 입력된다. $(3 \le N, M \le 50)$  둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 $(r, c)$와 처음에 로봇 청소기가 바라보는 방향 $d$가 입력된다. $d$가 0$0$인 경우 북쪽, 1$1$인 경우 동쪽, 2$2$인 경우 남쪽, 3$3$인 경우 서쪽을 바라보고 있는 것이다.

셋째 줄부터 $N$개의 줄에 각 장소의 상태를 나타내는 $N \times M$개의 값이 한 줄에 $M$개씩 입력된다. $i$번째 줄의 $j$번째 값은 칸 $(i, j)$의 상태를 나타내며, 이 값이 0$0$인 경우 $(i, j)$가 청소되지 않은 빈 칸이고, 1$1$인 경우 $(i, j)$에 벽이 있는 것이다. 방의 가장 북쪽, 가장 남쪽, 가장 서쪽, 가장 동쪽 줄 중 하나 이상에 위치한 모든 칸에는 벽이 있다. 로봇 청소기가 있는 칸은 항상 빈 칸이다.

 

출력

로봇 청소기가 작동을 시작한 후 작동을 멈출 때까지 청소하는 칸의 개수를 출력한다.

 

 

접근법

  1. 현재 위치가 청소되지 않았다면 청소
  2. 현재 방향에서 반시계 방향으로 탐색
    • 청소할 수 있는 공간이면 전진 → 1번
  3. 벽을 만나거나 청소할 수 있는 공간이 없는 경우
    • 방향을 유지한 채 후진 → 1번
    • 뒤쪽에 벽이 있을 경우 후진 불가 → 종료

 

 

문제 풀이

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

public class Main {
    static int N, M;
    static int count;
    static int[][] room;
    static int dx[] = {-1,0,1,0};  // 북동남서
    static int dy[] = {0,1,0,-1};

    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());

        room = new int[N][M];

        st = new StringTokenizer(br.readLine());

        int r = Integer.parseInt(st.nextToken());
        int c = Integer.parseInt(st.nextToken());
        int d = Integer.parseInt(st.nextToken());
        count = 1;

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                room[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        dfs(r, c, d);

        System.out.println(count);
    }

    static void dfs(int r, int c, int d) {
        room[r][c] = -1; // 현재 위치 청소

        // 반시계 방향으로 탐색
        for (int i = 0; i < 4; i++) {
            d = (d + 3) % 4; //
            int nx = r + dx[d];
            int ny = c + dy[d];

            // 범위 안에 있고 청소가 안된 구역이라면 count++, dfs 재귀
            if (ny >= 0 && ny < M && nx >= 0 && nx < N && room[nx][ny] == 0){
                count++;
                dfs(nx, ny, d);
                return;
            }
        }

        int back = (d + 2) % 4;
        int bx = r + dx[back];
        int by = c + dy[back];

        // 주변에 청소할 구역이 없으면 방향은 유지하면서 후진, dfs 재귀
        // 뒤쪽이 벽이면 후진 불가 -> 종료
        if (by >= 0 && by < M && bx >= 0 && bx < N && room[bx][by] != 1) {
            dfs(bx, by, d);
        }
        
    }
}
저작자표시 (새창열림)

'알고리즘 > 탐색' 카테고리의 다른 글

[LeetCode] 637. Average of Levels in Binary Tree - Java  (0) 2023.09.08
[LeetCode] 199. Binary Tree Right Side View - Java  (0) 2023.09.08
[백준] 4673 셀프 넘버 (완전탐색) - Java  (1) 2023.05.10
[백준] 1759 암호 만들기 (완전탐색) - Java  (1) 2023.05.10
[백준] 2110 공유기 설치 (이분탐색) - Java  (0) 2023.05.03
  1. 접근법
  2. 문제 풀이
'알고리즘/탐색' 카테고리의 다른 글
  • [LeetCode] 637. Average of Levels in Binary Tree - Java
  • [LeetCode] 199. Binary Tree Right Side View - Java
  • [백준] 4673 셀프 넘버 (완전탐색) - Java
  • [백준] 1759 암호 만들기 (완전탐색) - Java
jny0
jny0
성장일기
jny0
J N Y 0
jny0
  • 분류 전체보기 (192)
    • 트러블슈팅 (6)
    • Java (22)
    • HTML, CSS , JavaScript (7)
    • MySQL, DBMS (9)
    • GIT (6)
    • 객체지향의 사실과 오해 (3)
    • 자바 ORM 표준 JPA 프로그래밍 (13)
    • 알고리즘 (114)
      • 자료구조 (59)
      • 수학 (11)
      • 정렬 (2)
      • 그리디 (3)
      • DP (4)
      • 그래프 (3)
      • 탐색 (9)
      • 재귀 (2)
      • 문자열 (9)
      • 기타 (12)
    • CS (10)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기
  • 관리

공지사항

인기 글

태그

  • 프로그래머스
  • 영상후기
  • JS
  • 알고리즘
  • 자료구조
  • git
  • codeup
  • MySQL
  • 백준
  • db
  • Java
  • DP
  • JPA
  • 누적합
  • 구현
  • 그리디
  • method
  • 스택
  • 투포인터
  • BFS

최근 댓글

최근 글

hELLO · Designed By 정상우.
jny0
[백준] 14503 로봇 청소기 (DFS) - Java
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.