일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- spring
- php 프로그래밍 입문 3판
- 페이코 친구코드
- 자바 스프링
- 페이코 추천인
- php 프로그래밍 입문
- php 프로그래밍 입문 예제
- 스프링
- Flutter
- Java
- C
- 플러터
- 배열
- php 프로그래밍 입문 문제풀이
- 페이코 초대코드
- programmers
- 자바
- php
- 백준
- 페이코 추천인코드
- php 프로그래밍 입문 연습문제
- SWEA
- php 프로그래밍
- 플러터 개발환경 설정
- C언어
- 파이썬
- JAVA SPRING
- 최단 경로
- 한정 분기
- php 프로그래밍 입문 솔루션
Archives
- Today
- Total
11-07 11:40
ImJay
[BOJ/Java] 2174. 로봇 시뮬레이션 본문
반응형
[BOJ/Java] 2174. 로봇 시뮬레이션
문제 해석
이 문제는 격자 위에서 주어진 명령에 따라 로봇들을 움직이면서, 로봇이 벽에 부딪히거나 다른 로봇과 충돌하는 상황을 시뮬레이션하는 문제이다. 로봇은 네 방향 중 하나를 향하고 있으며, "F", "L", "R" 세 가지 명령을 수행할 수 있다. "F"는 전진, "L"은 좌회전, "R"은 우회전을 의미한다. 명령에 따라 로봇이 이동할 때마다 그 결과를 검사하여 충돌이나 벽에 부딪히는 상황을 감지해야 한다.
풀이 과정
이 자바 코드는 로봇의 위치, 방향, 그리고 이동 로직을 포함한다. 로봇은 Robot 클래스의 인스턴스로 관리되며, 격자는 maps 배열로 표현된다. maps 배열은 로봇의 위치 정보를 저장하고, 로봇들은 robots 배열에 저장된다.
- 입력 처리: 격자의 크기, 로봇의 수, 명령의 수를 입력받는다. 그 다음 각 로봇의 초기 위치와 방향을 입력받아 maps와 robots 배열에 저장한다.
- 명령 실행: 각 명령을 받아서 해당 로봇을 이동시키는 move 메소드를 호출한다. 이 메소드는 로봇의 이동, 회전을 처리하며, 로봇이 다른 로봇에 충돌하거나 벽에 부딪히는 경우 적절한 값을 반환한다.
- 충돌 및 벽 충돌 처리: move 메소드에서 반환된 값에 따라 충돌 메시지를 출력하거나 모든 명령이 성공적으로 수행되었으면 "OK"를 출력한다.
코드
package edu.ssafy.im.BOJ.Gold.G5.No2174;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
static int A, B, N, M;
static class Robot {
int r, c, d; // 로봇의 위치(r, c)와 방향(d)
public Robot(int r, int c, int d) {
this.r = r;
this.c = c;
this.d = d;
}
}
static int dr[] = { -1, 0, 1, 0 }; // 방향 벡터 (북, 동, 남, 서)
static int dc[] = { 0, 1, 0, -1 };
static Robot[] robots; // 로봇 객체 배열
static int maps[][]; // 격자 정보 (로봇의 위치 저장)
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringBuilder sb = new StringBuilder();
StringTokenizer st = new StringTokenizer(br.readLine());
A = Integer.parseInt(st.nextToken()); // 가로 크기
B = Integer.parseInt(st.nextToken()); // 세로 크기
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); // 로봇 수
M = Integer.parseInt(st.nextToken()); // 명령 수
robots = new Robot[N + 1];
maps = new int[B + 1][A + 1]; // 격자 초기화
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
int c = Integer.parseInt(st.nextToken());
int r = Integer.parseInt(st.nextToken());
String o = st.nextToken(); // 방향 문자
maps[B - r + 1][c] = i; // 격자에 로봇 번호 할당
switch (o) {
case "N":
robots[i] = new Robot(B - r + 1, c, 0);
break;
case "E":
robots[i] = new Robot(B - r + 1, c, 1);
break;
case "S":
robots[i] = new Robot(B - r + 1, c, 2);
break;
case "W":
robots[i] = new Robot(B - r + 1, c, 3);
break;
}
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int robotNum = Integer.parseInt(st.nextToken());
String order = st.nextToken();
int loopCnt = Integer.parseInt(st.nextToken());
int result = move(robotNum, order, loopCnt);
if (result == -1) { // 벽 충돌 처리
sb.append("Robot ").append(robotNum).append(" crashes into the wall");
bw.write(sb.toString());
bw.flush();
bw.close();
return;
}
if (result > 0) { // 다른 로봇과의 충돌 처리
sb.append("Robot ").append(robotNum).append(" crashes into robot ").append(result);
bw.write(sb.toString());
bw.flush();
bw.close();
return;
}
}
sb.append("OK"); // 모든 명령 성공 처리
bw.write(sb.toString());
bw.flush();
bw.close();
}
private static int move(int robotNum, String order, int loopCnt) {
for (int i = 0; i < loopCnt; i++) {
switch (order) {
case "F":
maps[robots[robotNum].r][robots[robotNum].c] = 0; // 현재 위치 초기화
int r = robots[robotNum].r += dr[robots[robotNum].d];
int c = robots[robotNum].c += dc[robots[robotNum].d];
if (r <= 0 || r > B || c <= 0 || c > A) return -1; // 벽 충돌 검사
if (maps[r][c] != 0) return maps[r][c]; // 다른 로봇과 충돌 검사
maps[robots[robotNum].r][robots[robotNum].c] = robotNum; // 업데이트된 위치에 로봇 번호 할당
break;
case "L":
robots[robotNum].d--; // 방향 왼쪽 회전
robots[robotNum].d = robots[robotNum].d == -1 ? 3 : robots[robotNum].d;
break;
case "R":
robots[robotNum].d++; // 방향 오른쪽 회전
robots[robotNum].d = robots[robotNum].d == 4 ? 0 : robots[robotNum].d;
break;
}
}
return 0;
}
}
시간 복잡도 분석
시간 복잡도는 주어진 명령의 수 𝑀과 각 명령에서 반복되는 최대 횟수 𝑙𝑜𝑜𝑝𝐶𝑛𝑡에 의해 결정된다. 최악의 경우, 각 명령이 격자의 최대 크기에 걸쳐 반복될 수 있으며, 이는 𝑂(𝑀×𝑙𝑜𝑜𝑝𝐶𝑛𝑡)으로 표현할 수 있다.
느낀점
이 문제를 통해 격자와 객체지향 프로그래밍을 활용한 복잡한 시뮬레이션 로직 구현의 중요성을 다시 한번 깨달았다. 추가로 예외 상황 처리의 중요성도 인지할 수 있었다. 또한, 로봇의 이동과 관련된 여러 경우의 수를 철저히 디버깅하면서 문제 해결 능력이 향상되었다고 느낀다.
반응형
'알고리즘 > BOJ - Java' 카테고리의 다른 글
[BOJ/Java] 14500. 테트로미노 (0) | 2024.04.22 |
---|---|
[BOJ/Java] 3055. 탈출 (0) | 2024.04.22 |
[BOJ/Java] 11403. 경로 찾기 (1) | 2024.04.21 |
[BOJ/Java] 15652. N과 M (4) (1) | 2024.04.21 |
[BOJ/Java] 1463. 1로 만들기 (0) | 2024.04.21 |
Comments