2174번: 로봇 시뮬레이션
첫째 줄에 두 정수 A, B가 주어진다. 다음 줄에는 두 정수 N, M이 주어진다. 다음 N개의 줄에는 각 로봇의 초기 위치(x, y좌표 순) 및 방향이 주어진다. 다음 M개의 줄에는 각 명령이 명령을 내리는 순
www.acmicpc.net
크게 어려운 점은 없는 문제인데,
board의 방향이 좌표평면과 똑같다는 점에서 유의해야 했다.
board[B+1][A+1] 크기로 선언해야하고, 나는 로봇의 x, y좌표를 입력받을 때 y좌표를 뒤집어서 저장해 주었다.
( 1,2,3,4) -> 각각 (4,3,2,1)로 저장
그 이후로는 내 행렬 모양대로 풀었다.
1. 로봇정보 저장
로봇행렬을 만들어서 각 인덱스에 로봇정보(로봇의 방향, x좌표, y좌표)를 저장하고,
int[][] board에는 로봇번호를 저장했다.
2. 방향전환
static char[] rotate = new char[]{'N','E','S','W'};
시계 방향 순서를 저장해놓고, 다음 방향을 찾는다.
LEFT회전의 경우, 현재 방향의 인덱스를 찾고, 1 감소시킨다.(0보다 작아지면 3으로 돌아감)
RIGHT회전의 경우, 현재 방향의 인덱스를 찾고 1 증가시킨다.(4보다 커지지 않도록 %4처리)
//아래코드는 RIGHT회전 코드
for(int dirIndex = 0; dirIndex<4; dirIndex++){
//현재 방향 찾아서 다음 인덱스로 바꿈
if(left_rotate[dirIndex] == nowDir){
dirIndex = (dirIndex+1)%4;
robots[robotNum].dir = left_rotate[dirIndex];
break;
}
}
(사실 dx, dy배열을 이용해 시계방향 순서대로 저장하고, 현재 방향을 int형 인덱스 값으로 저장하면 따로 현재방향의 인덱스를 찾아줄 필요가 없어서 이것보다 더 좋은 코드일 것 같다.)
3. 한칸 앞으로 이동
dx, dy 배열을 사용해 상하좌우로 이동한다.
로봇이 향하고 있는 방향에 따라 이동할 칸을 찾고, 충돌을 검사한다.
- 그 칸이 벽과 충돌하는지(0 or A+1/B+1)
- 다른 로봇과 충돌하는지(board값이 0이 아님)
충돌하지 않는 경우,
board값을 바꿔주고(현재값: 0, 이동할 위치: 로봇번호)
로봇 배열의 좌표도 바꿔준다.
전체 코드
package simulation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Q2174_로봇시뮬레이션 {
/*[골드5] Q2174 - 로봇 시뮬레이션*/
static int A, B, N, M;
static char[] rotate = new char[]{'N','E','S','W'}; //시계방향(right)
static int [] dx = new int[]{0,0,-1,1}; //N,S,W,E 순서
static int [] dy = new int[]{-1,1,0,0};
static int[][] board; //로봇이 위치하면 로봇 번호 저장, 아니면 0저장
static Robot[] robots;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
A = Integer.parseInt(st.nextToken());
B = Integer.parseInt(st.nextToken());
board = new int[B+1][A+1]; //1부터 사용
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
robots = new Robot[N+1]; //1부터 사용
M = Integer.parseInt(st.nextToken());
//로봇의 초기 위치
for(int i = 1; i<N+1; i++){
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = (B+1)-Integer.parseInt(st.nextToken()); //뒤집어서 저장
char dir = st.nextToken().charAt(0);
robots[i] = new Robot(x,y,dir);
board[y][x] = i;
}
for(int i = 0; i<M;i++){
st = new StringTokenizer(br.readLine());
int robotNum = Integer.parseInt(st.nextToken());
char order = st.nextToken().charAt(0);
int times = Integer.parseInt(st.nextToken());
//times만큼 반복
for(int t = 0; t<times; t++){
char nowDir = robots[robotNum].dir;
switch(order){
case 'L':
//다음 방향을 찾는다.
for(int dirIndex = 0; dirIndex<4; dirIndex++){
//현재 방향 찾아서 다음 인덱스로 바꿈
if(rotate[dirIndex] == nowDir){
dirIndex = (dirIndex-1)<0? 3 : dirIndex-1;
robots[robotNum].dir = rotate[dirIndex];
break;
}
}
break;
case 'R':
//다음 방향을 찾는다.
for(int dirIndex = 0; dirIndex<4; dirIndex++){
if(rotate[dirIndex] == nowDir){
dirIndex = (dirIndex+1)%4;
robots[robotNum].dir = rotate[dirIndex];
break;
}
}
break;
case 'F':
//한칸 앞으로 이동했을 때 좌표 구하기
int fowardIndex = -1;
switch(nowDir){
case 'N':
fowardIndex = 0;
break;
case 'S':
fowardIndex = 1;
break;
case 'W':
fowardIndex = 2;
break;
case 'E':
fowardIndex = 3;
break;
}
int nextX = robots[robotNum].x + dx[fowardIndex];
int nextY = robots[robotNum].y + dy[fowardIndex];
//벽과 충돌하는지(0 또는 A+1/B+1)
if(nextX==0 || nextX==A+1 || nextY ==0 || nextY == B+1){
System.out.println("Robot "+robotNum+" crashes into the wall");
System.exit(0);
}
//로봇과 충돌하는지(board가 0이 아님)
if(board[nextY][nextX] != 0){
System.out.println("Robot "+robotNum+" crashes into robot "+board[nextY][nextX]);
System.exit(0);
}
board[robots[robotNum].y][robots[robotNum].x] = 0;
board[nextY][nextX] = robotNum;
robots[robotNum].x = nextX;
robots[robotNum].y = nextY;
// System.out.println("("+robotNum+") "+nextX+" "+nextY+" "+nowDir);
break;
}
}
}
System.out.println("OK");
}
static class Robot{
int x, y;
char dir;
public Robot() {
}
public Robot(int x, int y, char dir) {
this.x = x;
this.y = y;
this.dir = dir;
}
}
}
'Java알고리즘' 카테고리의 다른 글
[BOJ][Java] Q14658 - 하늘에서 별똥별이 빗발친다 (0) | 2022.04.13 |
---|---|
[BOJ][Java]Q11967 - 불켜기 (0) | 2022.04.06 |
[BOJ][Java]Q18429 - 근손실 (0) | 2022.04.05 |
[개념] 순열, 조합, 부분집합 (0) | 2022.04.04 |
[BOJ][Java]Q15591 - MooTube (0) | 2022.03.16 |