문제
가로 A(1≤A≤100), 세로 B(1≤B≤100) 크기의 땅이 있다. 이 땅 위에 로봇들이 N(1≤N≤100)개 있다.

로봇들의 초기 위치는 x좌표와 y좌표로 나타난다. 위의 그림에서 보듯 x좌표는 왼쪽부터, y좌표는 아래쪽부터 순서가 매겨진다. 또한 각 로봇은 맨 처음에 NWES 중 하나의 방향을 향해 서 있다. 초기에 서 있는 로봇들의 위치는 서로 다르다.
이러한 로봇들에 M(1≤M≤100)개의 명령을 내리려고 한다. 각각의 명령은 순차적으로 실행된다. 즉, 하나의 명령을 한 로봇에서 내렸으면, 그 명령이 완수될 때까지 그 로봇과 다른 모든 로봇에게 다른 명령을 내릴 수 없다. 각각의 로봇에 대해 수행하는 명령은 다음의 세 가지가 있다.
- L: 로봇이 향하고 있는 방향을 기준으로 왼쪽으로 90도 회전한다.
- R: 로봇이 향하고 있는 방향을 기준으로 오른쪽으로 90도 회전한다.
- F: 로봇이 향하고 있는 방향을 기준으로 앞으로 한 칸 움직인다.
간혹 로봇들에게 내리는 명령이 잘못될 수도 있기 때문에, 당신은 로봇들에게 명령을 내리기 전에 한 번 시뮬레이션을 해 보면서 안전성을 검증하려 한다. 이를 도와주는 프로그램을 작성하시오.
잘못된 명령에는 다음의 두 가지가 있을 수 있다.
- Robot X crashes into the wall: X번 로봇이 벽에 충돌하는 경우이다. 즉, 주어진 땅의 밖으로 벗어나는 경우가 된다.
- Robot X crashes into robot Y: X번 로봇이 움직이다가 Y번 로봇에 충돌하는 경우이다.
입력
첫째 줄에 두 정수 A, B가 주어진다. 다음 줄에는 두 정수 N, M이 주어진다. 다음 N개의 줄에는 각 로봇의 초기 위치(x, y좌표 순) 및 방향이 주어진다. 다음 M개의 줄에는 각 명령이 명령을 내리는 순서대로 주어진다. 각각의 명령은 명령을 내리는 로봇, 명령의 종류(위에 나와 있는), 명령의 반복 회수로 나타낸다. 각 명령의 반복 회수는 1이상 100이하이다.
출력
첫째 줄에 시뮬레이션 결과를 출력한다. 문제가 없는 경우에는 OK를, 그 외의 경우에는 위의 형식대로 출력을 한다. 만약 충돌이 여러 번 발생하는 경우에는 가장 먼저 발생하는 충돌을 출력하면 된다.
예제 입력 1 복사
5 4
2 2
1 1 E
5 4 W
1 F 7
2 F 7
예제 출력 1 복사
Robot 1 crashes into the wall
풀이
아. 진짜 싫다. 처음에 구현할 때 생각했던게
A,B의 반전, 그리고 이에 따른 상, 하의 반전이다. 여기까진 생각했다.
그리고 나서 구현을 쭉했는데 몇몇 반례만 통과가 안되더라.
뭐지 ? 하고 디버깅만 1시간을 넘게했다.
알고보니 list에 넣을 때도 x,y를 반전시켜서 y,x로 넣은 것. 근데 Class에 선언된 x,y는 사실 상관 없던 것.
아. 진짜 싫다.
일단, 문제의 조건을 보면
1. 상,하가 반전되어 있어서 탐색할때 증감하는 부분도 반전이 되어야 한다.
2. A,B가 int[A][B]가 아니라 int[B][A] 이다. (이거 때문에 문제 몇번 읽었다. 인지부조화 오네)
3. 위 2번 조건에 따라 x와 y의 활용 또한 map[x][y]가 아니라 map[y][x]다.
위 3번 조건때문에 list에 넣을때도 y,x로 넣었는데 class에는 x,y로 선언되어있었다.
일단. 검사를 하다가 벽에 부딛히거나 다른 로봇과 부딛히면 로직을 끝내는 flag용 boolean exit을 사용했다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class BJ_2174_로봇시뮬레이션 {
public static class Robot{
int x;
int y;
int dir;
public Robot(int x, int y, int dir)
{
this.x = x;
this.y = y;
this.dir = dir;
}
}
static int A,B,N,M;
static int[][] map;
static int[][] deltas = {{0,1},{1,0},{0,-1},{-1,0}};
static boolean exit = false;
static ArrayList<Robot> list = new ArrayList<>();
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());
map = new int[B][A];
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
list.add(new Robot(-1,-1,-1));
for(int i=0; i<N; i++)
{
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken())-1;
int y = Integer.parseInt(st.nextToken())-1;
String d = st.nextToken();
int tempDir = -1;
if(d.equals("N")) tempDir = 0;
else if(d.equals("E")) tempDir = 1;
else if(d.equals("S")) tempDir = 2;
else if(d.equals("W")) tempDir = 3;
list.add(new Robot(x,y,tempDir));
map[y][x] = i+1;
}
for(int i=0; i<M; i++){
st = new StringTokenizer(br.readLine());
int index = Integer.parseInt(st.nextToken());
String com = st.nextToken();
int loof = Integer.parseInt(st.nextToken());
if(com.equals("L")) turnLeft(index,loof);
else if(com.equals("R")) turnRight(index,loof);
else if(com.equals("F")) go(index,loof);
if(exit) break;
}
if(!exit) System.out.println("OK");
}
public static void turnLeft(int index, int loof)
{
for(int i=0; i<loof; i++)
{
int dir = list.get(index).dir;
if(dir == 0) list.get(index).dir = 3;
else list.get(index).dir -= 1;
}
}
public static void turnRight(int index, int loof)
{
for(int i=0; i<loof; i++)
{
int dir = list.get(index).dir;
if(dir == 3) list.get(index).dir = 0;
else list.get(index).dir += 1;
}
}
public static void go(int index,int loof) {
int nx = list.get(index).x;
int ny = list.get(index).y;
int dir = list.get(index).dir;
for (int i = 0; i < loof; i++) {
nx += deltas[dir][0];
ny += deltas[dir][1];
if (nx < 0 || A <= nx || ny < 0 || B <= ny) {
System.out.println("Robot " + index + " crashes into the wall");
exit = true;
return;
}
if (map[ny][nx] != 0) {
System.out.println("Robot " + index + " crashes into robot " + map[ny][nx]);
exit = true;
return;
}
map[list.get(index).y][list.get(index).x] = 0;
map[ny][nx] = index;
list.get(index).x = nx;
list.get(index).y = ny;
}
}
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 10653 - 마라톤 2 (Java) (0) | 2024.05.06 |
---|---|
백준 2310 - 어드벤처 게임 (Java) (0) | 2024.05.05 |
백준 1799 - 비숍 (Java) (0) | 2024.05.03 |
백준 1655 - 가운데를 말해요(Java) (1) | 2024.05.02 |
백준 1039 - 교환 (Java) (0) | 2024.04.30 |