티스토리 뷰

Algorithm

[백준] G5 2174 로봇 시뮬레이션 (ja)

코딩브론즈 2021. 7. 29. 17:47

https://www.acmicpc.net/problem/2174

 

2174번: 로봇 시뮬레이션

첫째 줄에 두 정수 A, B가 주어진다. 다음 줄에는 두 정수 N, M이 주어진다. 다음 N개의 줄에는 각 로봇의 초기 위치(x, y좌표 순) 및 방향이 주어진다. 다음 M개의 줄에는 각 명령이 명령을 내리는 순

www.acmicpc.net

 

풀이

 

1) 로봇의 좌표와 방향을 담을 클래스 Robot을 생성한다.

2) List<Robot> 을 생성하여 입력된 N개의 로봇을 저장한다.

3) M번의 명령을 수행한다.

3-1) 명령을 수행하며 벽이나 로봇에 부딛히는지 확인한다. 문제가 없는 경우 OK를 출력한다.

 

주의사항

 

1) 숫자로 방향을 표시하면 방향을 전환을 할때 매우 편해진다. 특히 방향을 반시계 방향 순서대로 정하면 규칙을 찾기 용이해진다.

2) 로봇은 0번이 아니라 1번 로봇부터 존재한다. 따라서 정답에 +1을 해주던가 맨처음에 부딛히지 않는 로봇을 넣던가 해주자.

 

package com.baekJoon;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class BJ_G5_2174_로봇시뮬레이션 {
	static BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokens;
	static int A,B,N,M,map[][];
	static List<Robot> list = new ArrayList<>();
	public static void main(String[] args) throws NumberFormatException, IOException {
		input = new BufferedReader(new StringReader(src));
		tokens = new StringTokenizer(input.readLine());
		A = Integer.parseInt(tokens.nextToken());
		B = Integer.parseInt(tokens.nextToken());
		map = new int[B][A];
		tokens = new StringTokenizer(input.readLine());
		N = Integer.parseInt(tokens.nextToken());
		M = Integer.parseInt(tokens.nextToken());
		list.add(new Robot(0, 0, 0)); // 허허..
		for(int n=1; n<=N; n++) {
			tokens = new StringTokenizer(input.readLine());
			int c = Integer.parseInt(tokens.nextToken()) - 1;
			int r = B - Integer.parseInt(tokens.nextToken()) ;
			int d = 0;
			switch (tokens.nextToken().charAt(0)) {
			case 'N': // 상
				d = 0;
				break;
			case 'W': // 좌
				d = 1;
				break;
			case 'S': // 하
				d = 2;
				break;
			case 'E': // 우
				d = 3;
				break;
			}
			list.add(new Robot(r, c, d));
			map[r][c] = n;
		}
		boolean isOver = false;
		outer : for(int m=0; m<M; m++) {
			tokens = new StringTokenizer(input.readLine());
			int no = Integer.parseInt(tokens.nextToken());
			char cmd = tokens.nextToken().charAt(0);
			int repeat = Integer.parseInt(tokens.nextToken());
			
			if(cmd == 'L') {
				repeat = repeat % 4;
				int nd = list.get(no).d;
				for(int i=0; i<repeat; i++) {
					nd = (nd+1) % 4;
				}
				list.get(no).d = nd;
			}else if(cmd == 'R') {
				repeat = repeat % 4;
				int nd = list.get(no).d;
				for(int i=0; i<repeat; i++) {
					nd = (nd+3) % 4;
				}
				list.get(no).d = nd;
			}else {
				int nr = list.get(no).r;
				int nc = list.get(no).c;
				int d = list.get(no).d;
				for(int i=0; i<repeat; i++) {
					nr = nr + dr[d];
					nc = nc + dc[d];
					if(!isIn(nr, nc)) { // 장외
						System.out.println("Robot "+no+" crashes into the wall");
						isOver = true;
						break outer;
					}
					if(map[nr][nc] != 0) { // 다른 로봇과 부딪침
						System.out.println("Robot "+no+" crashes into robot "+map[nr][nc]);
						isOver = true;
						break outer;
					}
				}
				// 별다른 이상이 없다면 list와 map을 초기화 해주자
				map[list.get(no).r][list.get(no).c] = 0;
				map[nr][nc] = no;
				list.get(no).r = nr;
				list.get(no).c = nc;
			}
		}
		if(!isOver) {
			System.out.println("OK");
		}
	}
	
	static int dr[] = {-1,0,1,0}; // 상 좌 하 우
	static int dc[] = {0,-1,0,1};
	
	static boolean isIn(int r, int c) {
		return (r>=0 && c>=0 && r<B && c<A);
	}
	
	static class Robot{
		int r;
		int c;
		int d;
		public Robot(int r, int c, int d) {
			super();
			this.r = r;
			this.c = c;
			this.d = d;
		}
		@Override
		public String toString() {
			return "Robot [r=" + r + ", c=" + c + ", d=" + d + "]";
		}
	}
	static String src =
			"5 4\r\n"
			+ "2 2\r\n"
			+ "1 1 E\r\n"
			+ "5 4 W\r\n"
			+ "1 F 7\r\n"
			+ "2 F 7";
}

 

후기

 

 방향 전환 시 일정한 규칙을 찾고 공식을 만들면 상당히 편하다는 것을 알게된 후 방향전환 문제에 대한 접근법을 바꿔보니 정답률이 높아지고 풀이 시간 또한 짧아지는것 같다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
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
글 보관함