https://www.acmicpc.net/problem/13567
난이도 : S4
Tag : Simulation
풀이 일자 : 2025-03-11
문제 탐색하기
초기 조건
- 처음 로봇위치 : (0, 0)
- 동쪽 방향을 보고 있음
- M : 정사각형 S의 한 변의 길이 (1 <= M <= 1,000)
- n : 로봇이 수행할 명령어 수 (1 <= n <= 1,000)
동작
- TURN 0 : 현재 위치에서 왼쪽으로 90도 회전
- TURN 1 : 현재 위치에서 오른쪽으로 90도 회전
- MOVE d : 현재 방향으로 d만큼 움직임 (1 <= d <= 1,000)
모든 명령 수행 후 로봇이 S의 경계를 포함한 안에 있으면 좌표 출력
경계를 벗어났다면 -1 출력
즉 (0,0) 동쪽 방향부터 시작하여 로봇이 명령어 수만큼 움직였을 때
경계를 포함한 내부에 로봇이 있다면 로봇의 좌표를
범위를 벗어낫다면 -1을 출력하면 됩니다.
가능한 시간복잡도
이 문제는 그대로 구현하는 시뮬레이션 문제이므로 총 명령어 수 O(n) 만큼 연산이 필요합니다.
만약, 지도의 특정 위치에 함정이 있거나 이동이 불가능한 지역이 있었다면,
모든 좌표를 저장하고 하나하나 계산해야 하므로 O(1,000,000) (1,000 × 1,000)까지 증가할 수도 있습니다.
하지만 이 문제는 맵을 저장할 필요 없이 단순히 경계를 벗어나는지만 확인하면 됩니다.
따라서 최악의 경우에도 O(1,000) 연산만 수행하므로 충분히 빠르게 해결 가능합니다.
알고리즘 선택
시뮬레이션으로 직접 구현해 보겠습니다.
dx[], dy[] 테크닉과 시계방향 회전, 반시계방향 회전 방법만 잘 알고 있다면 어렵지 않은 문제입니다.
먼저 처음에 동쪽을 향하고 있다고 했으므로 dx, dy의 처음을 동쪽으로 설정해줍니다.
그리고 시계방향으로 좌표를 세팅해 줍니다.
// 동(→), 남(↓), 서(←), 북(↑)
int[] dx = {1, 0, -1, 0};
int[] dy = {0, 1, 0, -1};
이후 방향을 바꾸고 싶을 때는 모듈러 연산(%)을 활용하면 됩니다.
현재 방향을 dir이라고 한다면:
- 시계방향으로 이동할 경우 dir = (dir+1)%4
- 반시계 방향은 dir = ((dir+4)-1)%4로 설정할 수 있습니다.
코드 설계하기
- 입력 처리 (M, n 입력받기)
- 초기 위치, 방향 설정 (x = 0, y = 0, dir = 0)
- 명령어 처리 (TURN, MOVE)
- 방향을 회전(TURN)할 경우, dir 값만 변경
- 이동(MOVE d)할 경우, dx[], dy[]를 이용해 이동
- 이동 후 경계를 벗어났다면 즉시 -1 출력 후 종료
- 모든 명령 수행 후, 로봇이 경계 안에 있다면 최종 위치 출력
정답코드
import java.util.*;
import java.io.*;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int m = Integer.parseInt(st.nextToken());
int n = Integer.parseInt(st.nextToken());
int x = 0, y = 0, dir = 0;
int[] dx = {0, 1, 0, -1};
int[] dy = {1, 0, -1, 0};
boolean isValid = true;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
String op = st.nextToken();
int num = Integer.parseInt(st.nextToken());
if (op.equals("MOVE")) {
x += dx[dir] * num;
y += dy[dir] * num;
} else {
if (num == 0) dir = (dir + 1) % 4; //시계방향
else dir = (dir + 3) % 4; //반시계방향
}
if (x < 0 || y < 0 || x >= m || y >= m) {
isValid = false;
break;
}
}
System.out.println(isValid ? (y + " " + x) : -1);
}
}
If you want to change direction afterwards, you can use the modular operation (%).
'Algorithm > Baekjoon' 카테고리의 다른 글
[백준] 2615번 - 오목 java (0) | 2025.03.13 |
---|---|
[백준] 2503번 - 숫자 야구 java (0) | 2025.03.12 |
[백준] 2096번 - 내려가기 java (0) | 2025.03.10 |
[백준] 1149번 - RGB거리 java (0) | 2025.03.09 |
[백준] 14430번 - 자원 캐기 java (0) | 2025.03.08 |