| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- 프리티어
- UNIDEV
- 게임개발동아리
- 개발공부
- NAT gateway
- spring ai
- AWS
- Redis
- openAI API
- 체크인미팅
- 전국대학생게임개발동아리연합회
- 인프라
- 라피신
- 생활코딩
- 티스토리챌린지
- bastion host
- 도커
- 42서울
- 캡스톤디자인프로젝트
- UNICON2023
- CICD
- EC2
- 백엔드개발자
- Route53
- UNICON
- 프로그래밍
- 프롬프트엔지니어링
- 스프링부트
- Spring boot
- 오블완
- Today
- Total
Hyun's Wonderwall
[백준 골드5] 14503번: 로봇 청소기 (구현) - Java 본문
14503번: 로봇 청소기
https://www.acmicpc.net/problem/14503
문제
로봇 청소기와 방의 상태가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오.
로봇 청소기가 있는 방은 NxM 크기의 직사각형으로 나타낼 수 있으며, 1x1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 벽 또는 빈 칸이다. 청소기는 바라보는 방향이 있으며, 이 방향은 동, 서, 남, 북 중 하나이다. 방의 각 칸은 좌표 (r, c)로 나타낼 수 있고, 가장 북쪽 줄의 가장 서쪽 칸의 좌표가 (0, 0), 가장 남쪽 줄의 가장 동쪽 칸의 좌표가 (N-1, M-1)이다. 즉, 좌표 (r, c)는 북쪽에서 (r+1)번째에 있는 줄의 서쪽에서 (c+1)번째 칸을 가리킨다. 처음에 빈 칸은 전부 청소되지 않은 상태이다.
로봇 청소기는 다음과 같이 작동한다.
1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
1) 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
2) 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
1) 반시계 방향으로 90도 회전한다.
2) 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
3) 1번으로 돌아간다.
입력
첫째 줄에 방의 크기 N과 M이 입력된다. (3<=N, M<=50) 둘째 줄에 처음에 로봇 청소기가 있는 칸의 좌표 (r, c)와 처음에 로봇 청소기가 바라보는 방향 d가 입력된다. d가 0인 경우 북쪽, 1인 경우 동쪽, 2인 경우 남쪽, 3인 경우 서쪽을 바라보고 있는 것이다.
셋째 줄부터 N개의 줄에 각 장소의 상태를 나타내는 N x M개의 값이 한 줄에 M개씩 입력된다. i번째 줄의 j번째 값은 칸 (i, j)의 상태를 나타내며, 이 값이 0인 경우 (i, j)가 청소되지 않은 빈 칸이고, 1인 경우 (i, j)에 벽이 있는 것이다. 방의 가장 북쪽, 가장 남쪽, 가장 서쪽, 가장 동쪽 줄 중 하나 이상에 위치한 모든 칸에는 벽이 있다. 로봇 청소기가 있는 칸은 항상 빈 칸이다.
출력
로봇 청소기가 작동을 시작한 후 작동을 멈출 때까지 청소하는 칸의 개수를 출력한다.
예제 입력 1
3 3
1 1 0
1 1 1
1 0 1
1 1 1
예제 출력 1
1
예제 입력 2
11 10
7 4 0
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 1 1 1 1 0 1
1 0 0 1 1 0 0 0 0 1
1 0 1 1 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 1 0 1
1 0 0 0 0 0 1 1 0 1
1 0 0 0 0 0 1 1 0 1
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1
예제 출력 1
57
풀이
시도
방이 벽으로 둘러싸여있는 모습이, 좌표평면이 나오는 문제에서 2차원 배열을 가로세로 +2한 크기로 생성하는 것과 비슷한 느낌이었다.
로봇청소기 작동 로직의 2번 중 '뒤에 벽이 있을 때'란 뒤 칸의 원소 값이 1일 때를 의미한다. 벽이 방의 중간에도 있음에 주의.
문제 이해 및 디버깅까지 오래 걸렸지만... 한번에 맞아서 기쁘다!
어려웠던 부분: 보드 상의 좌표, 로봇청소기가 이동가능한 방향, 다음 회전 각도를 한번에 생각하는 것 (머릿속으로 그림을 그리며 풀었다)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main
{
private void solution() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
int r = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
int[][] board = new int[n][m];
for(int i=0; i<n; i++) {
st = new StringTokenizer(br.readLine());
for(int j=0; j<m; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
int count = 0;
int[][] dir = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
while (true) {
if (board[r][c] == 0) {
board[r][c] = -1;
count++;
}
boolean flag = false; // 청소되지 않은 빈 칸이 있는가?
for(int i=0; i<4; i++) {
int lookx = r+dir[(4-d+i)%4][0];
int looky = c+dir[(4-d+i)%4][1];
if (board[lookx][looky] == 0) {
r = lookx;
c = looky;
d = (3+d-i)%4;
flag = true;
// System.out.println("loc: " + r + ", " + c + ": " + d);
break;
}
}
if (flag == true)
continue;
if (d==0 && board[r+1][c] != 1)
r++;
else if (d==1 && board[r][c-1] != 1)
c--;
else if (d==2 && board[r-1][c] != 1)
r--;
else if (d==3 && board[r][c+1] != 1)
c++;
else
break;
}
System.out.println(count);
}
public static void main(String[] args) throws Exception {
new Main().solution();
}
}'Study > PS' 카테고리의 다른 글
| [백준 골드3] 15685번: 드래곤 커브 (구현) - Java (0) | 2025.07.18 |
|---|---|
| [백준 실버1] 1283번: 단축키 지정 (구현) - Java (1) | 2025.07.18 |
| [백준 실버2] 11501번: 주식 (그리디) - Java (1) | 2025.07.10 |
| [백준 실버3] 18310번: 안테나 (그리디) - Java (0) | 2025.07.10 |
| [백준 실버1] 1946번: 신입 사원 (그리디) - Java (1) | 2025.07.10 |