본문 바로가기
Computer Science/Algorithm

[백준] 3190 - 뱀 (Python)

by 수제햄버거 2021. 7. 3.
728x90
반응형

문제 출처 :

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

 

3190번: 뱀

 'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임

www.acmicpc.net

문제 풀이 :

  • 문제 자체가 그냥 시뮬레이션 문제이다. 특히나 이런류의 문제는 GUI까지 구현해서 게임을 만드는 프로젝트 등으로 학교에서 많이 했을꺼라고 생각한다.
  • 시키는대로 구현하면 되는데 신경썻던 부분이 두 개 정도 있었던 것 같다.
    • 뱀을 어떤 자료구조에 넣어서 관리 할 것인가? --> 앞뒤로 빼기 쉬워야 한다고 생각해서(자료를) Deque 구조를 사용했다.
    • 문제를 보면 사과가 있는 칸과 없는 칸에 대해서 꼬리가 움직인다 움직이지 않는다로 써있는데 그냥 사과 먹으면 길이가 1칸 늘어나는거고, 안먹으면 그냥 전체가 이동하는거다. 뭔가 말이 어렵게 쓰여져있다.
import sys
from collections import deque
#import numpy as np

N = int(sys.stdin.readline())
K = int(sys.stdin.readline())
maps = [[0 for _ in range(N)] for _ in range(N)]
for _ in range(K):
    y, x = map(int, sys.stdin.readline().split())
    # 사과 위치 표시하기.
    maps[y - 1][x - 1] = 2

# 방향이 바뀌어야 하는 시간대 저장하기.
change = {}
L = int(sys.stdin.readline())
for _ in range(L):
    time, letter = sys.stdin.readline().split()
    change[int(time)] = letter

# 처음 위치, 처음 움직일 방향 설정
maps[0][0] = 1
move = (0, 1)


# 방향 바꾸는 함수
def change_dir(move, Letter):
    y, x = move
    # x축 기준으로 이동할 때
    if y == 0:
        if Letter == 'D':
            if x > 0:
                return (1, 0)
            else:
                return (-1, 0)
        else:
            if x > 0:
                return (-1, -0)
            else:
                return (1, 0)
    # y축 기준으로 이동할 때
    elif x == 0:
        if Letter == 'D':
            if y > 0:
                return (0, -1)
            else:
                return (0, 1)
        else:
            if y > 0:
                return (0, 1)
            else:
                return (0, -1)


time = 0
y, x = 0, 0
# 뱀 좌표 저장하기
snake = deque()
snake.append((y, x))
while True:
    #print(snake)
    #print(np.array(maps))
    time += 1
    dy, dx = move
    ny, nx = y + dy, x + dx
    # 보드 위에 있을 때
    if 0 <= ny < N and 0 <= nx < N:
        # 사과인 경우
        if maps[ny][nx] == 2:
            snake.appendleft((ny, nx))
            maps[ny][nx] = 1
        # 빈 칸인 경우
        elif maps[ny][nx] == 0:
            maps[ny][nx] = 1
            snake.appendleft((ny, nx))
            # 맨 뒷꼬리 부분을 빼낸다.
            taily, tailx = snake.pop()
            maps[taily][tailx] = 0

        # 자기 몸에 부딪혔으므로 더 이상 진행하지 않는다.
        elif maps[ny][nx] == 1:
            break
        y, x = ny, nx

        # 방향을 변환해야 하는 시간인 경우
        if time in change:
            move = change_dir(move, change[time])

    # 보드를 벗어난 경우이므로 반복문을 종료한다.
    else:
        break
print(time)
반응형