[백준 C++] 2174 로봇 시뮬레이션

이성훈·2022년 3월 13일
0
post-custom-banner

문제

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

로봇들의 초기 위치는 x좌표와 y좌표로 나타난다. 위의 그림에서 보듯 x좌표는 왼쪽부터, y좌표는 아래쪽부터 순서가 매겨진다. 또한 각 로봇은 맨 처음에 NWES 중 하나의 방향을 향해 서 있다. 초기에 서 있는 로봇들의 위치는 서로 다르다.

이러한 로봇들에 M(1≤M≤100)개의 명령을 내리려고 한다. 각각의 명령은 순차적으로 실행된다. 즉, 하나의 명령을 한 로봇에서 내렸으면, 그 명령이 완수될 때까지 그 로봇과 다른 모든 로봇에게 다른 명령을 내릴 수 없다. 각각의 로봇에 대해 수행하는 명령은 다음의 세 가지가 있다.

  1. L: 로봇이 향하고 있는 방향을 기준으로 왼쪽으로 90도 회전한다.
  2. R: 로봇이 향하고 있는 방향을 기준으로 오른쪽으로 90도 회전한다.
  3. F: 로봇이 향하고 있는 방향을 기준으로 앞으로 한 칸 움직인다.
    간혹 로봇들에게 내리는 명령이 잘못될 수도 있기 때문에, 당신은 로봇들에게 명령을 내리기 전에 한 번 시뮬레이션을 해 보면서 안전성을 검증하려 한다. 이를 도와주는 프로그램을 작성하시오.

잘못된 명령에는 다음의 두 가지가 있을 수 있다.

  1. Robot X crashes into the wall: X번 로봇이 벽에 충돌하는 경우이다. 즉, 주어진 땅의 밖으로 벗어나는 경우가 된다.
  2. Robot X crashes into robot Y: X번 로봇이 움직이다가 Y번 로봇에 충돌하는 경우이다.

입력

첫째 줄에 두 정수 A, B가 주어진다. 다음 줄에는 두 정수 N, M이 주어진다. 다음 N개의 줄에는 각 로봇의 초기 위치(x, y좌표 순) 및 방향이 주어진다. 다음 M개의 줄에는 각 명령이 명령을 내리는 순서대로 주어진다. 각각의 명령은 명령을 내리는 로봇, 명령의 종류(위에 나와 있는), 명령의 반복 회수로 나타낸다. 각 명령의 반복 회수는 1이상 100이하이다.

출력

첫째 줄에 시뮬레이션 결과를 출력한다. 문제가 없는 경우에는 OK를, 그 외의 경우에는 위의 형식대로 출력을 한다. 만약 충돌이 여러 번 발생하는 경우에는 가장 먼저 발생하는 충돌을 출력하면 된다.

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

풀이

이런 좌표문제의경우, 입력값을 꼼꼼히 확인하자.

문제에서 x,y좌표를 위와같은형태로 주어진다.
간단히, x, y, a, b를 바꾸어 풀수있겠으나, 필자의경우 위의 좌표계대로 구현했다.

많이 수정했다.

#define _CRT_SECURE_NO_WARNINGS 
#include <bits/stdc++.h>
int a, b, n, m, **map, **robots; 
int dx[5] = {0, 1, 0, -1, 0}; //E:1  S:2  W:3  N:4 (시계방향)
int dy[5] = {0, 0, 1, 0, -1};

void playGame() {
	int r, cnt; //로봇번호r 반복횟수cnt
	char order; //명령어
	bool END_GAME = false;
	while (m--) {

		scanf("%d%c%c%d", &r, &order, &order, &cnt);
		int y, x, dir; //x, y좌표, 현재방향dir
		for(int i = 0 ; i < b; i++)
			for(int j = 0 ; j < a ; j++)
				if (robots[i][j] == r) { //로봇위치를 찾음
					y = i; x = j; dir = map[i][j];
				}
		if (END_GAME)
			continue;

		if (order == 'L') { //반시계방향 턴
			while (cnt--) {
				dir--;
				if (dir == 0)
					dir = 4;
			}
			map[y][x] = dir; //재설정
		}
		else if (order == 'R') { //시계방향 턴
			while (cnt--) {
				dir++;
				if (dir == 5)
					dir = 1;
			}
			map[y][x] = dir;
		}
		else if (order == 'F') { //전진
			int yy = y, xx = x; //다음위치
			while (cnt--) {
				//로봇위치 변경1
				robots[yy][xx] = 0;
				map[yy][xx] = 0;
				yy += dy[dir]; xx += dx[dir];  //다음위치 계산
				//벽에부딪히는경우
				if (yy <= -1 || b <= yy || xx <= -1 || a <= xx) {
					printf("Robot %d crashes into the wall", r);
					END_GAME = true;
					break;
				}
				//로봇에 충돌하는경우
				if (!END_GAME && robots[yy][xx] != 0) {
					printf("Robot %d crashes into robot %d", r, robots[yy][xx]);
					END_GAME = true;
					break;
				}
				//로봇위치 변경2
				robots[yy][xx] = r;
				map[yy][xx] = dir;

			}
		}

	}

	if (!END_GAME) printf("OK");
}

int main(char c) {
	scanf("%d%d%d%d", &a, &b, &n, &m);
	map = new int* [b];
	robots = new int* [b];
	for (int i = 0; i < b; i++) {
		map[i] = new int[a];
		robots[i] = new int[a];
		for (int j = 0; j < a; j++) {
			map[i][j] = 0; //초기화
			robots[i][j] = 0;
		}
	}

	for (int i = 0, x, y; i < n; i++) {
		scanf("%d%d%c%c", &x, &y, &c, &c); //%c%c:공백읽고 방향을읽음
		if (c == 'E') {
			map[b - y][x - 1] = 1; //입력좌표계 고려
		}
		else if (c == 'S') {
			map[b - y][x - 1] = 2;
		}
		else if (c == 'W') {
			map[b - y][x - 1] = 3;
		}
		else if (c == 'N') {
			map[b - y][x - 1] = 4;
		}
		robots[b - y][x - 1] = i + 1; //로봇번호기록
	}

	playGame();

	return 0;
}
profile
I will be a socially developer
post-custom-banner

0개의 댓글