메이쁘

(JAVA) 백준 14503번 : 로봇 청소기 본문

Algorithm/Baekjoon

(JAVA) 백준 14503번 : 로봇 청소기

메이쁘 2020. 4. 10. 01:30

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

 

14503번: 로봇 청소기

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

www.acmicpc.net

 

 

시뮬레이션 문제다.

 

이 문제는

 

뱀 문제와 비슷하다.

https://maivve.tistory.com/84

 

(JAVA) 백준 3190번 : 뱀

https://www.acmicpc.net/problem/3190 3190번: 뱀 문제 'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신..

maivve.tistory.com

 

또한,

 

문제에 명시되어있는 흐름대로 알고리즘을 작성하면 된다.

 

 

매커니즘 대신 주의할 부분만 포스팅하고 마치겠다.

 

 

 

 

 

위 캡쳐 화면 중 2.b 를 구현하기 위해

왼쪽으로 90도 방향을 바꾸는 코드를 짜야한다.

 

이는 

 

direction = direction == 0 ? 3 : direction - 1;

 

로 표현할 수 있다. (문제를 보면 0 ~ 3까지 순서대로 시계방향으로 주어졌기 때문이다.)

 

 

다음으로,

 

2.c2.d 를 구분하기 위해

처음 바라봤던 방향의 한칸 뒤가 벽 인지 아닌지 파악해둬야 한다.

 

그래서 벽인 경우

네 방향을 체크하는 반복문을 다시 실행해야 한다.

 

 

벽이 아닌 경우에는

뒤로 한 칸 이동한 후 계속 진행하면 되는데

 

이 때, 방향은 처음 바라봤던 방향을 유지해야 한다.  (이것때메 틀릴 뻔했다.)

 

 

 

간단하죠?

 

 

감사합니다.

 

소스코드


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
// 로봇 청소기
// 시뮬레이션 문제
public class p14503 {
static int[] moveX = { 0, 1, 0, -1 };
static int[] moveY = { -1, 0, 1, 0 };
static int[][] map; // 0 : 빈칸. 1 : 벽. 2 : 청소 완료
static int n, m;
static int direction;
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.valueOf(st.nextToken());
m = Integer.valueOf(st.nextToken());
map = new int[n][m];
st = new StringTokenizer(br.readLine());
int r = Integer.valueOf(st.nextToken());
int c = Integer.valueOf(st.nextToken());
direction = Integer.valueOf(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.valueOf(st.nextToken());
}
}
int result = clean(r, c);
System.out.println(result);
}
static int clean(int y, int x) {
int count = 0;
while(true) {
map[y][x] = 2; // 청소 완료
count++;
for(int i = 0; i < moveX.length; i++) { // 왼쪽방향부터 차례대로 탐색
direction = direction == 0 ? moveX.length - 1 : direction - 1;
int nextX = x + moveX[direction];
int nextY = y + moveY[direction];
if((x < 0 || x >= m) || (y < 0 || y >= n)) { // 애초에 벗어나는 조건이 따로 없음.
return -1;
}
if(map[nextY][nextX] == 0) { // 벽 또는 청소 완료상태
x = nextX;
y = nextY;
break;
}
if(i == moveX.length - 1) { // 한 바퀴 돈 이후
// 후방 파악하기
int backDirection = direction <= 1 ? moveX.length - Math.abs(direction - 2) : direction - 2;
int backX = x + moveX[backDirection];
int backY = y + moveY[backDirection];
// 후방이 벽인 경우
if(map[backY][backX] == 1) {
return count;
}
// 초기화(뒤로 이동 후 재탐색)
x = backX;
y = backY;
i = -1;
}
}
}
}
}
view raw p14503.java hosted with ❤ by GitHub

 

 

Comments