백준 14503 - 로봇 청소기

Updated:

Java

14503 번 - 로봇 청소기

문제

접근 방법

문제에서는 [북 : 0, 동 : 1, 남 : 2, 서 : 3]으로 제시하였지만,
문제 풀이를 위해 왼쪽으로 이동할 때는 [북 -> 서 -> 남 -> 동] 이므로, 입력 받은 d의 동, 서를 바꾸어 주었다.

while 반복문을 시작하며 4개 방향을 탐색하며, 빈 공간을 찾았으면 continue로 while문 위쪽으로 돌아온다.
만약 4개 방향이 막혀있거나, 청소가 되어있으면 for문 다음으로 넘어간다.
여기서 후진한 방향이 벽이 아니면 while 초기로 돌아가고, 막혀있으면 while문을 종료한다.

주의할 점은, while문이 한번 돌았을 때 후진으로 들어온 것인지, 빈 공간을 찾아서 들어온 것인지 구분하여야 한다.
따라서 isclean boolean으로 판별하였다.

코드

import java.util.*;
import java.io.*;

public class Main {
	static int n, m, result;
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    	
    	StringTokenizer stk = new StringTokenizer(br.readLine());
    	n = stoi(stk.nextToken());
    	m = stoi(stk.nextToken());
    	// --------초기화--------
    	int y,x,ny,nx,d;
    	int count = 0;
    	boolean isClean = true;
    	// 북 서 남 동
    	int[] dy = {-1,0,1,0};
    	int[] dx = {0,-1,0,1};
    	
    	int[][] map = new int[n][m];
    	
    	stk = new StringTokenizer(br.readLine());
    	
    	y = stoi(stk.nextToken());
    	x = stoi(stk.nextToken());
    	d = stoi(stk.nextToken());
    	
    	// 동과 서를 바꾸어준다.
    	if(d == 1)
    		d = 3;
    	else if(d == 3)
    		d = 1;
    	
    	for(int i = 0; i < n; i++) {
    		stk = new StringTokenizer(br.readLine());
    		for(int j = 0; j < m; j++) {
    			map[i][j] = stoi(stk.nextToken());
    		}
    	}

    	// --------구현 시작--------
    	next: while(true) {
    		// 현재 위치를 청소한다.
    		map[y][x] = 2;
    		// 후진으로 온것이 아닐 경우 == 청소가능
    		if(isClean)
    			count++;
    		// 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.
    		for(int i = 0; i < 4; i++) {
    			// 왼쪽으로 회전시킨다.
    			d = (d + 1) % 4;
    			
    			ny = y + dy[d];
    			nx = x + dx[d];
    			// 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
    			if(isIn(ny,nx) && map[ny][nx] == 0) {
    				y = ny;
    				x = nx;
    				isClean = true;
    				continue next;
    			}
    		}
    		
    		// 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 
    		// 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
    		ny = y + dy[(d + 2) % 4];
    		nx = x + dx[(d + 2) % 4];
    		
    		if(isIn(ny, nx) && map[ny][nx] != 1) {
    			y = ny;
    			x = nx;
    			isClean = false;
    		}
    		// 후진도 할 수 없는 경우에는 작동을 멈춘다.
    		else {
    			break;
    		}
    	}
    	
    	System.out.println(count);
    	
    	br.close();
	}
	
	static boolean isIn(int y, int x) {
		if(0 <= y && y < n && 0 <= x && x < m)
			return true;
		return false;
	}
	static int stoi(String str) {
    	return Integer.parseInt(str);
    }
}

총평

후기

개선할 점