본문 바로가기
algorithm/Baekjoon

[백준] 14503.로봇 청소기 (java) / 시뮬레이션

by buddev 2020. 2. 26.

@시뮬레이션 / 1h 3m (필기 13m 포함)

약간 까다로운 시뮬레이션 문제였다(문제의 단어 의미가 헷갈려서..)

처음에는 답이 안 나왔는데, 디버깅을 꼼꼼하게 해서 금방 해결했다!

 

 

문제 링크

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

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 벽 또는 빈 칸이다. 청소기는 바라보는 방향이 있으며, 이 방향은 동, 서, 남, 북중 하나이다. 지도의 각 칸은 (r, c)로 나타낼 수 있고, r은 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로 부터 떨어진 칸의 개수이다. 로봇 청소기는 다음

www.acmicpc.net

 

구현 방법

로봇 청소기는 1번과 2번을 반복하기 때문에

2개의 while문을 사용했다.

 

while문이 두 개 이기 때문에, 빠져 나올 수 있게 flag를 이용했다.

 

while (flag) { //1번을 위한 반복문

    현재 위치를 청소;

    

    while (true) { //2번을 위한 반복문

         if (사방을 다 돌았는데도 갈 곳이 없다면) { //이걸 방향 증가 전, while의 가장 첫 부분에 넣어 줘야 한다!

               if (뒷 칸으로 이동 가능하다면) //c

               else //d

         }

 

         왼쪽 방향으로 턴;

 

         if (왼쪽 방향이 청소 가능하다면) { // a

         else // b

    }

}

 

구현 포인트

예전에 풀었을 때의 코드를 보니, 경계체크를 해 줬었는데

이 문제는 이미 모든 외곽이 벽으로 주어지기 때문에, 경계를 벗어날 일이 없다.

즉, 경계 체크를 따로 해 줄 필요가 없다.

 

 

코드

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

public class Main {
	
	private static int N, M, map[][];
	private static int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		map = new int[N][M];
		
		int x, y, d;
		st = new StringTokenizer(br.readLine());
		x = Integer.parseInt(st.nextToken());
		y = Integer.parseInt(st.nextToken());
		d = Integer.parseInt(st.nextToken());
		
		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());
		}
		System.out.println(clean(x, y, d));
	}

	private static int clean(int x, int y, int d) {
		int dirCount = 0, clean = 0, nx, ny;
		boolean flag = true;
		
		while (flag) {
			if (map[x][y] == 0) {
				map[x][y] = 2;
				clean++;
			}
			
			while (true) {
				if (dirCount == 4) {
					nx = x - dx[d];
					ny = y - dy[d];
					
					if (map[nx][ny] == 1) {	//뒷칸도 벽 
						flag = false;
						break;
					} else {
						x = nx;
						y = ny;
						dirCount = 0;
					}
				}
				
				d = (d + 3) % 4;
				nx = x + dx[d];
				ny = y + dy[d];
				
				if (map[nx][ny] == 0) {
					dirCount = 0;
					x = nx; y = ny;
					break;
				} else {
					dirCount++;
					continue;
				} 
			}
		}
		return clean;
	}
}

 

예전보다 훨씬 간결하게 풀어서, 기분이 좋다.

 

끝!

댓글