티스토리 뷰
문제 - (https://www.acmicpc.net/problem/14503)
문제에서 주어진 로봇 청소기의 작동 방법대로 구현하면 되는 문제였다.
시뮬레이션 문제들은 문제를 먼저 이해하는 것이 중요한데, 나는 문제 하는데 시간이 좀 걸렸다ㅠㅠ
- 로봇 청소기 작동 순서 -
- 현재 위치를 청소한다.
- 현재 위치에서 현재 방향을 기준으로 왼쪽방향부터 차례대로 탐색을 진행한다.
- 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면, 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
- 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.
- 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
- 네 방향 모두 청소가 이미 되어있거나 벽이면서, 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
내 코드에 주석과 함께 적어놨으니 참고하면 된다.
코드를 보기 전에, 짚고 넘어가야할 부분이 있을 것 같아 설명하겠다.
static int[] dx = {-1, 0, 1, 0}; // 북 동 남 서
static int[] dy = {0, 1, 0, -1};
static int[] dirLeft = {3, 0, 1, 2}; // 왼쪽
static int[] dirBack = {2, 3, 0, 1}; // 후진
바로 이부분!
주석에 설명이 있지만 헷갈릴 수 있어 머릿속에 되새길 겸 설명하겠다.
문제에서 "방향 d가 주어진다. d가 0인 경우에는 북쪽을, 1인 경우에는 동쪽을, 2인 경우에는 남쪽을, 3인 경우에는 서쪽을 바라보고 있는 것"이라고 했다. 이것을 염두에 두고 아래 표를 보자.
변수명/d | 0 (북) | 1 (동) | 2 (남) | 3 (서) |
dirLeft | 3 | 0 | 1 | 2 |
dirBack | 2 | 3 | 0 | 1 |
예를 들어서 이 표의 의미를 설명하자면
0(북) 일 때의 왼쪽은 3(서)이고, 뒤쪽은 2(남)이라는 뜻이다.
따라서 dirLeft에 현재 보고 있는 방향을 인덱스로 사용하면 현재 보고있는 방향에서 왼쪽은 어느 방향인지 알 수 있다.
로봇 청소기의 위치를 그 방향으로 이동시키면 끝!!!
int x = 현재 위치의 x좌표;
int y = 현재 위치의 y좌표;
int dir = 현재 보고있는 방향;
int left = dirLeft[dir];
int nx = x + dx[left];
int ny = y + dy[left];
int back = dirBack[dir];
int bx = x + dx[back];
int by = y + dy[back];
📌주의할 점
- "현재 방향을 기준으로 왼쪽 방향부터"와 같이 헷갈릴 수 있는 부분은 정확히 하고 넘어가야 한다.
😅실수
- 문제를 정확히 이해하고 코딩해나가자.. 대충 이해하고 시작하면 나중에 더 답 없어짐
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
// 골드5 - 1사간 10분
public class RoboticVacuumCleaner {
static int N;
static int M;
static int[][] map;
static int rR;
static int rC;
static int rDir;
static int[] dx = {-1, 0, 1, 0}; // 북 동 남 서
static int[] dy = {0, 1, 0, -1};
static int[] dirLeft = {3, 0, 1, 2}; // dirLeft[i] = i가 0,1,2,3 일 때 왼쪽이 되는 곳은 dx[i],dy[i]임
static int[] dirBack = {2, 3, 0, 1}; // 후진
static int answer = 0;
static void recursion(int x, int y, int dir, int end) {
/* 1 */
// 현재 위치 청소
if (map[x][y] == 0) {
map[x][y] = 2;
answer++;
// print();
}
/* 2 */
int currentLeft = dirLeft[dir];
int nx = x + dx[currentLeft];
int ny = y + dy[currentLeft];
if (nx < 0 || ny < 0 || nx >= N || ny >= M) return;
if (map[nx][ny] == 0) {
/* 2-1 */
// 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면,
// 그 방향으로 회전한 다음 한 칸을 전진하고 1번부터 진행한다.
recursion(nx, ny, currentLeft, 0);
} else {
// 왼쪽 방향에 청소할 공간이 없다면,
if (end != 4) {
/* 2-2 */
// 그 방향으로 회전하고 2번으로 돌아간다.
recursion(x, y, currentLeft, end + 1);
} else {
// 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는,
int back = dirBack[dir];
int bx = x + dx[back];
int by = y + dy[back];
if (bx < 0 || by < 0 || bx >= N || by >= M) return;
if (map[bx][by] != 1)
/* 2-3 */
// 바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다.
recursion(bx, by, dir, 0);
else
/* 2-4 */
// 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
return;
}
}
}
static void print() {
System.out.println("--------------------");
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
}
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());
map = new int[N][M];
st = new StringTokenizer(br.readLine());
rR = Integer.parseInt(st.nextToken());
rC = Integer.parseInt(st.nextToken());
rDir = 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());
}
}
recursion(rR, rC, rDir, 0);
System.out.println(answer);
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 13458번 / Java / 시험 감독 - 그리디 (0) | 2020.06.25 |
---|---|
[백준] 15685번 / Java / 드래곤 커브 - 구현, 시뮬레이션 (0) | 2020.06.25 |
[백준] 14502번 / Java / 연구소 - DFS, 완전탐색 (0) | 2020.06.24 |
[백준] 14891번 / Java / 톱니바퀴 - 구현, 시뮬레이션, 재귀풀이 (0) | 2020.06.23 |
[백준] 14888번 / Java / 연산자 끼워넣기 - 완전탐색, 백트래킹 (0) | 2020.06.23 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 사다리 조작
- Access-Control-Allow-Origin
- 구현
- Greedy
- 인구이동
- withCredentials
- 16234
- 완전탐색
- 재귀
- 14891
- 시뮬레이션
- header
- 배열순회
- 코딩테스트
- 자바
- 백준
- dfs
- 코테
- 코딩테스트 연습
- 프로그래머스
- 브라우저 요청
- 톱니바퀴
- 드래곤 커브
- 구명보트
- 큰 수 만들기
- 그리디
- 아기상어
- 우선순위큐
- BOJ
- java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함