Development Logs/Algorithms

[JAVA] 백준 14503번 : 로봇 청소기 (삼성 SW 역량 테스트 기출 문제)

유뱅유뱅뱅 2020. 8. 18. 18:58

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

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어

www.acmicpc.net

문제

DFS 문제라고 생각하고 풀었는데 stackoverflow가 자꾸 떠서 다른 사람 풀이 참고하여 풀었다. (알고보니 구현 문제)

 

해결 방안

문제에서의 로봇 청소기 작동 방법에 맞춰서 구현해주면 된다.

while 두개를 이용하여 구현하였으며 코드를 보면 1, 2 조건에 따른 코드를 구현하였다. 

 

코드

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

// 로봇 청소기
// 청소하는 영역의 갯수를 구하는 프로그램
// 청소기는 바라보는 방향이 있음
// (r,c) r: 북쪽으로부터 떨어진 칸의 갯수, c: 서쪽으로부터 떨어진 칸의 갯수
// 현재 방향을 기준으로 왼쪽 방향부터 차례대로 탐색을 진행함
public class Main {

	static int N; // 세로 (3~50)
	static int M; // 가로 (3~50)
	static int[][] map;
	
	static int r; // 로봇청소기 좌표(r,c)
	static int c; 
	static int d; // 바라보는 방향 (0:북, 1:동, 2:남, 3:서)
	static int[] dx = {-1, 0, 1, 0};
	static int[] dy = {0, 1, 0, -1};
	static int cleanSite = 0;
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String str;

		str = br.readLine();
		N = Integer.parseInt(str.split(" ")[0]);
		M = Integer.parseInt(str.split(" ")[1]);
		map = new int[N][M];
		
		str = br.readLine();
		r = Integer.parseInt(str.split(" ")[0]);
		c = Integer.parseInt(str.split(" ")[1]);
		d = Integer.parseInt(str.split(" ")[2]);
		
		StringTokenizer st;
		for(int i=0; i<N; i++) {
			str = br.readLine();
			st = new StringTokenizer(str, " ");
			for(int j=0; j<M; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		// ========= 입력 끝 ==========
		
		cleaning();
		System.out.println(cleanSite);
	}
	
	static void cleaning() {
		
		int dirCnt = 0; 
		int nx,ny;
		boolean flag = true;
		
		while(flag) {
			// 1. 현재 위치 청소
			if(map[r][c] == 0) {
				map[r][c] = 2;
				cleanSite++;
			}
			
			// 2. 탐색
			while(true) {
				if(dirCnt == 4) {
					nx = r - dx[d];
					ny = c - dy[d];
					
					// d. 뒷칸이 벽인 경우 작동 멈춤
					if(map[nx][ny] == 1) {
						flag = false;
						break;
					}
					// c. 후진
					else if(map[nx][ny] == 2) {
						r = nx;
						c = ny;
						dirCnt = 0;
					}
				}
				
				d--;
				if(d == -1)
					d = 3;
				nx = r + dx[d];
				ny = c + dy[d];
				
				// a. 한칸 전진
				if(map[nx][ny] == 0) {
					dirCnt = 0;
					r = nx;
					c = ny;
					break;
				}
				// b. 2번으로 돌아감
				else {
					dirCnt++;
					continue;
				}
				
			}
		}
	}

}