코딩테스트/백준

로봇시뮬레이션 Python(백준, BAEKJOON)

멍토 2020. 7. 1.

난이도 : Gold 5

문제번호 : 2174

문제 주소 및 출처입니다.

www.acmicpc.net/problem/2174

 

2174번: 로봇 시뮬레이션

문제 가로 A(1≤A≤100), 세로 B(1≤B≤100) 크기의 땅이 있다. 이 땅 위에 로봇들이 N(1≤N≤100)개 있다. 로봇들의 초기 위치는 x좌표와 y좌표로 나타난다. 위의 그림에서 보듯 x좌표는 왼쪽부터, y좌표

www.acmicpc.net


목차

1. 문제 설명

2. 문제 해석

3. 소스 코드


1. 문제 설명

가로 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를, 그 외의 경우에는 위의 형식대로 출력을 한다. 만약 충돌이 여러 번 발생하는 경우에는 가장 먼저 발생하는 충돌을 출력하면 된다.

예시

입력 출력
5 4
2 2
1 1 E
5 4 W
1 F 7
2 F 7
Robot 1 crashes into the wall

2. 문제풀이

로봇의 위치를 보정해주지 않고 처리하다 보니 계속 에러가 나서 아예 갈아엎어서 풀었다.

처음 시작위치를 보정해주는 작업부터 했는데 시작위치가 0이 아니라 1부터 시작해서 x축은 -1을 해주었다.

Y축은 아래가 시작점이므로 최대크기에서 빼주어 보정을 해주었다.

동서남북 이동또한 맵과 마찬가지로 맞추어 이동하도록 설정했다.

이 부분만 처리를 잘했으면 뒷부분은 어렵지 않게 구현이 가능할것이다.


아래에는 명령어를 처리하는 로직을 썻는데 전진과 회전으로 분기를 처리하였다.

회전은 따로 함수로 빼서 만들었다.


전진명령의 경우 이동할 위치가 맵에 벗어나는지, 로봇이 있는지, 앞의 조건을 모두 통과했는지로 판단했다.


이해가 되지않는다면 주석을 참고하면 될것같다.


3. 소스코드

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# Gold 5 2174 로봇 시뮬레이션
 
direction_num = {'N'0'E'1'S'2'W':30:'N'1:'E'2:'S'3:'W'}
# 문제를 기준으로 동서남북 이동시 필요한 y,x를 적어준다.
direction_to_position = {'N': (-10), 'E': (01), 'S': (10), 'W':(0-1)}
 
 
def find_direction(start, command, repeat):
    # 회전횟수는 4번 마다 원위치이므로 모듈연산
    repeat %= 4 
    # 시작번호를 받아와서
    start_num = direction_num[start]
    # 방향에 맞춰 돌려본다.
    if command == 'L':
        start_num-=repeat
        # 0보다 적어지면 보정
        if start_num < 0: start_num += 4
    # 반대도 마찬가지
    else:
        start_num+=repeat
        if start_num > 3: start_num -= 4
    return direction_num[start_num]
 
 
answer = None
A, B = map(int, input().split())
field = [[0 for _ in range(A)] for _ in range(B)]
# 0번 인덱스는 쓰지않을것이기 때문에 임시번호를 넣어준다.
robots = [0]
N,M = map(int, input().split())
for i in range(N):
    # 입력이 y,x가 아니라 x,y로 들어온다 주의
    x, y, direction = input().split()
    # 그림은 1번부터 쓰는데 인덱스는 0번부터 시작해서 보정해준다.
    x, y = int(x)-1int(y)
    # 그림은 밑에서부터 시작하니까 y축을 뒤집어서 위치를 보정해준다.
    robots.append([B-y, x, direction])
    field[B-y][x] = i+1
# 위의 작업이 끝나면 예시와 같은 모양이 나오게 된다.
 
for i in range(M):
    # 로봇번호, 명령어, 횟수
    idx, command, repeat = input().split()
    idx, repeat = int(idx), int(repeat)
    y, x, direction = robots[idx]
    # 전진일때 처리
    if command == 'F':
        # 이동위치에 필요한 값을 받는다.
        dy, dx = direction_to_position[direction]
        # 이동해야 하는 횟수만큼 반복한다.
        for i in range(repeat):
            # 이동할 좌표를 계산하고
            move_y, move_x = y+dy, x+dx
            # 맵밖으로 벗어나지 않았다면 동작
            if 0 <= move_y < B and 0 <= move_x < A:
                # 이동하는 위치에 로봇이 있다면 충돌처리
                if field[move_y][move_x]:
                    answer = 'Robot {} crashes into robot {}'.format(idx, field[move_y][move_x])
                    break
                # 이동이 가능하고 이동할 위치에 아무것도 없다면
                else:
                    # 현재위치에 정보를 없애고
                    field[y][x]=0
                    # 이동위치에 로봇정보를 표시하고
                    field[move_y][move_x] = idx
                    # 현재 정보를 이동한 위치정보로 갱신해준다.
                    y, x = move_y, move_x
                    # 로봇의 정보또한 마찬가지로 갱신해준다.
                    robots[idx] = [move_y, move_x, direction]
            # 맵 밖으로 나갔다면 밖으로 나갔다고 정답 갱신하기
            else:
                answer = 'Robot {} crashes into the wall'.format(idx)
                break
    # 회전일때 처리
    else:
        # 현재보는 방향과 명령과 횟수를 전달하여 정보갱신
        robots[idx][2= find_direction(direction, command, repeat)
    # 정답이 생겼다면 충돌이 생긴것이다.
    if answer: break
 
# 정답이 비어있다면 통과로 변경해주기
if not answer: answer = 'OK'
print(answer)

댓글

💲 광고입니다.