사용한 자료구조 / 알고리즘
- 덱(deque)
접근 방법
고전 게임 '스네이크'를 직접 구현하는 알고리즘 문제다.
구현해야 하는 요소는 다음과 같다
- 사과를 먹을 때마다 뱀의 길이가 증가.
- 뱀이 자신을 물거나 벽에 닿으면 종료.
- 뱀이 성공적으로 이동할 경우, 뱀 꼬리를 옮겨줌.
- 시간에 따른 이동방향 변경
구현한 방법
- 뱀의 길이: 1로 시작해서 사과를 만날 때마다 증가하는 int 변수.
- 뱀의 좌표: deque로 관리. len(deque)가 뱀의 길이보다 클 경우, popleft 후 지도에서 뱀을 지워야 한다. (가장 먼저 들어갔던 곳 == 발자취 == 꼬리)
- 시간 값을 key로 하는 dictionary 를 선언. 매 초마다 value가 있는지 확인한다.
느낀점, 특이사항
문제를 꼼꼼하게 읽어야 한다. '뱀의 움직임'을 어떻게 구현할 것인가가 명확하게 나와있다. 이런 요소들을 명확하게 파악한 후 문제를 푼다면 시행착오를 많이 줄일 수 있을 것이다.
- X초가 지나고 방향을 전환한다.
- 뱀의 머리가 늘어나서 한 칸 전진 후 꼬리에서 한 칸 줄어든다.
pprint 모듈을 import한 후 좌표평면을 보면서 푸는 방법도 괜찮았다.
from collections import deque
import sys
input = sys.stdin.readline
# 0 우, 1 상, 2 좌, 3 하
dx = [1, 0, -1, 0]
dy = [0, -1, 0, 1]
# 1. 입력
# 1-1. 좌표평면 설정 뱀 초기값 설정
N = int(input()) # 지도의 크기 입력
sq_lst = [[0]*N for _ in range(N)] # 2차원 좌표평면 선언
sq_lst[0][0] = 1 # 뱀 표시
# 4: 사과
# 1: 뱀
# 1-2. 사과 위치 입력
K = int(input()) # 사과의 갯수
for i in range(K):
y, x = map(int, input().split())
sq_lst[y-1][x-1] = 4 # 사과를 '4'로 표시
# 1-3. 명령 입력.
L = int(input()) # 명령의 갯수
direction_dict = dict() # dict 형태로 선언.
for i in range(L): # 명령의 갯수에 따라
sec, direction = map(str, input().split())
direction_dict[int(sec)] = direction # 초 - 명령을 딕셔너리 형태로 삽입.
# 2. 선언
d = 0 # 방향 초기값
sec = 0 # '게임 플레이 한 시간' 초기값
snake_Q = deque() # 뱀의 좌표
snake_Q.append([0, 0]) # 큐에 뱀 좌표 초기값 입력
snake_len = 1 # 뱀의 길이. 초기값 == 1
# 3. 연산
while True:
# 3-1. 스네이크의 움직임 확인
sec += 1 # 1초 가산.
y, x = snake_Q[-1] # 마지막 값(머리) 확인
nx = x + dx[d] # 다음에 갈 예정인 곳의 x좌표
ny = y + dy[d] # ''' y좌표
# 3-2. 스네이크가 움직임
if nx >= N or nx < 0 or ny >= N or\
ny < 0 or sq_lst[ny][nx] == 1: # 벽에 부딪히거나 꼬리를 물 때
break # 함수를 종료.
if sq_lst[ny][nx] == 4: # 4과를 먹었을 때
snake_len += 1 # 스네이크 길이 1 증가
sq_lst[ny][nx] = 1 # 사과를 먹거나 말거나 상관 없이
snake_Q.append([ny, nx]) # Q에 좌표 넣기
# 3-3. 움직임을 끝낸 스네이크가 꼬리를 끌고 감
while len(snake_Q) != snake_len:
tail_y, tail_x = snake_Q.popleft()
sq_lst[tail_y][tail_x] = 0
# 3-4 방향전환이 있을 경우 방향 전환.
if direction_dict.get(sec) == 'L':
d += 1
if d == 4:
d = 0
elif direction_dict.get(sec) == 'D':
d -= 1
if d == -1:
d = 3
print(sec) # 출력
'BOJ > 구현' 카테고리의 다른 글
21608. 상어 초등학교 - 구현, 시뮬레이션, counter sort, 해시 테이블. 파이썬 (0) | 2021.10.25 |
---|---|
17070. 파이프 옮기기 - DP + 비트마스킹. 파이썬 (0) | 2021.10.22 |
14500. 테트로미노 -브루트 포스, 구현, 시뮬레이션. [파이썬] (0) | 2021.10.15 |
14503. 로봇청소기 - 시뮬레이션, 구현 (0) | 2021.09.27 |