728x90
반응형
· 문제링크
https://www.acmicpc.net/problem/2174
2174번: 로봇 시뮬레이션
첫째 줄에 두 정수 A, B가 주어진다. 다음 줄에는 두 정수 N, M이 주어진다. 다음 N개의 줄에는 각 로봇의 초기 위치(x, y좌표 순) 및 방향이 주어진다. 다음 M개의 줄에는 각 명령이 명령을 내리는 순
www.acmicpc.net
· 핵심
1. 방향에 따라 움직임 : dx-dy 테크닉 사용
2. 격자 내 움직임 : in_range 함수로 판단
3. 편한 좌표계로 변환(convert_coordinates) 및 문자 방향 동(0)남(1)서(2)북(3)에 맞게 변환(direction)
≫ (기존) 1base의 왼쪽 하단(1, 1) - 오른쪽 상단(n, m) → (변형) 0base의 왼쪽 상단(0, 0) - 오른쪽 하단(n, m)
# 좌표계 좌표 변환(열좌표, 행좌표. 행의 수)
def convert_coordinates(c, r, R, C):
new_r = R - 1 - r
new_c = c
return new_c, new_r
# 열, 행, 방향
robots =[['열', '행', '방향']] + [list(input().split()) for _ in range(N)]
for idx, robot in enumerate(robots):
if idx != 0:
# 1base 변환, 방향 -> cur_dir로 변경
cc, cr = convert_coordinates(int(robot[0]) - 1,int(robot[1]) - 1, R, C)
robots[idx] = [cc, cr, direction(robot[2])]
board[cr][cc] = idx
4. 시뮬레이션
- wall_flag와 robot_flag 도입 이유 : 벽 충돌을 체크하기 위한 wall_flag, 로봇끼리의 충돌을 체크하기 위하 robot_flag 설정 → 정상적으로 작동하는 경우를 판단(wall_flag == True && robot_flag == True)
- not in_range일 때 -1, -1를 return하는 이유 : in_range가 False라는 것은 nr, nc가 격자를 벗어났다는 것이다. 출력값에 벽에 부딪힐 경우 특정 좌표 등이 필요하지 않아서 -1, -1로 출력값을 기록한다.
- if board[nr][nc] != 0을 체크하는 이유: 0이 아니라는 것은 다른 로봇이 존재한다는 것을 의미한다. 또 nr, nc를 return하는 이유는 board[nr][nc]에 존재하는 로봇의 숫자가 필요하기 때문이다.
- 기존의 로봇이 존재하는 위치인 board[cr][cc] = 0 으로 초기화 → 현재 위치 변경 cr, cc = nr, nc→ 변경된 위치에 로봇 위치 시키기
# cr, cc 기존 위치 초기화
board[cr][cc] = 0
cr, cc = nr, nc
board[cr][cc] = robot_num
· 코드(Python)
# https://www.acmicpc.net/problem/2174
C, R = map(int, input().split())
N, M = map(int, input().split())
board = [[0 for _ in range(C)] for _ in range(R)]
# cur_dir 결정
def direction(prompt):
if prompt == "E":
return 0
elif prompt == "S":
return 1
elif prompt == "W":
return 2
else:
return 3
# 좌표계 좌표 변환(열좌표, 행좌표. 행의 수)
def convert_coordinates(c, r, R, C):
new_r = R - 1 - r
new_c = c
return new_c, new_r
# 열, 행, 방향
robots =[['열', '행', '방향']] + [list(input().split()) for _ in range(N)]
for idx, robot in enumerate(robots):
if idx != 0:
# 1base 변환, 방향 -> cur_dir로 변경
cc, cr = convert_coordinates(int(robot[0]) - 1,int(robot[1]) - 1, R, C)
robots[idx] = [cc, cr, direction(robot[2])]
#처음에 존재하는 로봇의 위치 기록
board[cr][cc] = idx
# 로봇번호 1base, 명령어, 반복회수
cmds = [list(input().split()) for _ in range(M)]
# NameError 방지
nr, nc = 0, 0
wall_flag = True
robot_flag = True
# 동(0)남(1)서(2)북(3)
dr = [0, 1, 0, -1]
dc = [1, 0, -1, 0]
# 격자 내 이동
def in_range(r, c):
return 0 <= r < R and 0 <= c < C
# `2개 이상일 때 로봇의 마지막 도착지를 결정할 수 있어야함.`
def simulate(robot_num, prompt, cnt, cr, cc, cur_dir):
global nr, nc, wall_flag, robot_flag
for _ in range(cnt):
if prompt == "R":
cur_dir = (cur_dir + 1) % 4
elif prompt == "L":
cur_dir = (cur_dir + 3) % 4
else:
nr = cr + dr[cur_dir]
nc = cc + dc[cur_dir]
if not in_range(nr, nc):
wall_flag = False
return robot_num, cur_dir, -1, -1
else:
if board[nr][nc] != 0:
robot_flag = False
return robot_num, cur_dir, nr, nc
# cr, cc 기존 위치 초기화
board[cr][cc] = 0
cr, cc = nr, nc
board[cr][cc] = robot_num
return robot_num, cur_dir, cr, cc
for cmd in cmds:
# 로봇번호(int), 명렁어(string), 반복회수(int)
robot_num, prompt, cnt = int(cmd[0]), cmd[1], int(cmd[2])
# 로봇의 위치 : 열(int), 행(int), 방향(int)
cc, cr, cur_dir = robots[robot_num][0], robots[robot_num][1], robots[robot_num][2]
robot_num, cur_dir, nr, nc = simulate(robot_num, prompt, cnt, cr, cc, cur_dir)
if not robot_flag:
print(f"Robot {robot_num} crashes into robot {board[nr][nc]}")
break
if not wall_flag:
print(f"Robot {robot_num} crashes into the wall")
break
# 이동 후 위치 기록
robots[robot_num] = [nc, nr, cur_dir]
if wall_flag and robot_flag:
print("OK")
728x90
반응형
'PS > 백준' 카테고리의 다른 글
[백준/BOJ] 2623번 - 음악프로그램 (Python) (0) | 2023.09.29 |
---|---|
[백준/BOJ] 1347번 - 미로 만들기 (Python, Java) (0) | 2023.09.25 |
[백준/BOJ] 2252번 - 줄 세우기 (Python, Java) (0) | 2023.09.25 |
[백준/BOJ] 14891번 - 톱니바퀴(Python, Java) (0) | 2023.09.22 |
[백준/BOJ] 14499번 - 주사위 굴리기(Python) (0) | 2023.09.13 |