로봇 시뮬레이션
가로 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를, 그 외의 경우에는 위의 형식대로 출력을 한다. 만약 충돌이 여러 번 발생하는 경우에는 가장 먼저 발생하는 충돌을 출력하면 된다.
좌표 때문에 머리 터질뻔 했다.
역시 문제를 잘 읽어야해...
A, B가 각각 가로, 세로 길이로 우리가 흔히 쓰는 xy좌표이다.
그래서 행렬과 반대로 적용해야하며 특히, 행은 순서도 반대이다.
구현 시뮬레이션이라 크게 다른 어려운 점은 없었다.
import sys
# 땅 크기
A, B = map(int,sys.stdin.readline().split())
total = [[0] * (A+1) for _ in range(B+1)]
# 방향에 따라 이동할 좌표 설정
dir = ["N","E","S","W"]
dirs = [(1,0),(0,1),(-1,0),(0,-1)]
# 로봇 수, 로봇의 명령 수
N, M = map(int,sys.stdin.readline().split())
# 로봇 초기 위치 및 설정
robots = [[]]
for i in range(1,N+1):
robot = list(sys.stdin.readline().split())
# 숫자로 바꿔서 입력
robot[0] = int(robot[0])
robot[1] = int(robot[1])
# 방향을 좌표 인덱스로 변환
robot[2] = dir.index(robot[2])
# 로봇 숫자를 추가하여 저장
robots.append([i] + robot)
# 좌표에 로봇 위치시키기
for i in range(1,N+1):
total[B - robots[i][2] + 1][robots[i][1]] = robots[i][0]
# 명령 (로봇 번호, 명령 종류, 횟수)
opers = []
for _ in range(M):
opers.append(list(sys.stdin.readline().split()))
ans = "OK"
for oper in opers:
ck = False
# 좌우 회전은 나머지를 사용해서 설정
if oper[1] == "L":
robots[int(oper[0])][3] = (robots[int(oper[0])][3] - int(oper[2])) % 4
elif oper[1] == "R":
robots[int(oper[0])][3] = (robots[int(oper[0])][3] + int(oper[2])) % 4
# 전진
elif oper[1] == "F":
# 지금의 자리를 0으로 초기화
total[B - robots[int(oper[0])][2] + 1][robots[int(oper[0])][1]] = 0
# 전진하는 과정
for _ in range(int(oper[2])):
# 이동
robots[int(oper[0])][2] += dirs[robots[int(oper[0])][3]][0]
robots[int(oper[0])][1] += dirs[robots[int(oper[0])][3]][1]
# 이동 좌표가 범위 안 일때
if 1<= robots[int(oper[0])][2] <= B and 1<= robots[int(oper[0])][1] <= A:
pass
# 이동 좌표가 범위 밖 일때
else:
ck = True
ans = "Robot "+oper[0]+" crashes into the wall"
break
# 다른 번호를 만날 때(다른 로봇과 겹침)
if total[B - robots[int(oper[0])][2] +1][robots[int(oper[0])][1]] != 0:
ck = True
ans = "Robot "+oper[0]+" crashes into robot "+str(total[B - robots[int(oper[0])][2] +1][robots[int(oper[0])][1]])
break
if ck:
break
# 아무 에러 없이 통과하면 해당자리에 로봇 위치
total[B - robots[int(oper[0])][2] + 1][robots[int(oper[0])][1]] = int(oper[0])
if ck:
break
print(ans)
'@@@ 알고리즘 > 백준 스터디' 카테고리의 다른 글
9765(여섯 방정식) - 시간 초과 - 참고 - 해결 (0) | 2021.09.01 |
---|---|
14267(회사 문화 1) - 시간 초과 - 해결 (0) | 2021.08.28 |
21738(얼음깨기 펭귄) - 시간초과 - 해결(참고) (0) | 2021.08.26 |
2922(즐거운 단어) - 해결 (0) | 2021.08.26 |
20164(홀수 홀릭 호석) - 해결 (0) | 2021.08.25 |