![[BOJ] 백준 3190 뱀 Python](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRkscd%2FbtsC9zpTDwp%2FzhTn61G2P0TFSLtGaH3uJ1%2Fimg.png)
[BOJ] 백준 3190 뱀 Python알고리즘 & 코테2024. 1. 8. 05:05
Table of Contents
3190번: 뱀
'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임
www.acmicpc.net
문제풀이
이 문제는 근본적으로 뱀이 움직일때마다 움직인 뱀의 머리를 큐에 저장하고 뱀의 꼬리를 큐에서 pop하는 문제이다.
자세하게는 맵에 놓인 사과를 먹으면 꼬리를 pop하지 않고 사과를 먹지 못하면 pop한다.
그러다가 뱀이 자기자신의 몸과 닿거나 맵을 나가는경우 종료시킨다.
이 문제를 풀면서 유의해야했던 점은 뱀의 방향설정과 사과가 먹혔다면 먹힌 사과를 삭제해야하는 부분이었다.
맵에서 사과를 삭제해야하는 개념은 문제의 예제에서 확인할 수 없어 스스로 검증해야한다.
1. 먼저 입력을 받고 사과의 위치, 뱀의 위치, 뱀의 움직임,뱀의 방향을 저장한다. 아까 말했듯 뱀의 방향설정은 뱀이 우측으로 돌거나 좌측으로 도는 두가지 경우밖에 없기 때문에 direction = 0(뱀이 초기에 동쪽을 봄)으로 설정했다면 이동될 좌표 설정은 [동,남,서,북]을 기준으로 dx,dy를 작성한다.
2. 뱀의 머리에 대해서 이동시키기 전에 뱀의 방향변환 정보를 확인하여 회전 또는 그대로 놔둠의 논리를 진행시켰다.
그 다음 뱀을 이동시키며 사과를 먹었다면 꼬리를 큐에서 꺼내지(popleft) 않고, 사과를 못 먹었다면 꺼낸다.
3. 뱀이 사과를 먹었다면 사과가 있던 좌표를 [-1,-1]로 초기화시키며 사과의 먹힘처리를 한다.
사과의 먹힘 처리를 하지 않는다면 예외케이스에서 뱀이 같은 사과에 대해 길이가 한번 더 길어질 수 있기 때문에 반드시 해주어야한다. → 이 처리를 하지 않으면 예제가 다 맞게 나와도 19%에서 막히게 됨....
Code
from sys import stdin
from collections import deque
input = stdin.readline
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
direction = 0
def solve():
sec = 0
snake_loc = deque([[0, 0]])
N = int(input())
K = int(input())
apple_loc = []
for _ in range(K):
apple_loc.append(list(map(int, input().split())))
for i in apple_loc:
for j in range(2):
i[j] += -1
L = int(input())
snake_move = []
for i in range(L):
snake_move.append(list(map(str, input().split())))
snake_move[i][0] = int(snake_move[i][0])
while True:
k = one_sec_after(snake_loc, apple_loc, sec, snake_move, N)
if not k:
break
sec += 1
print(sec + 1)
def one_sec_after(snake_loc, apple_loc, sec, snake_move, N):
global direction
y, x = snake_loc[-1][0], snake_loc[-1][1]
for i in snake_move:
for j in range(len(snake_move)):
if i[0] == sec:
turn(i[1])
break
nx = x + dx[direction]
ny = y + dy[direction]
if [ny, nx] in snake_loc or nx < 0 or nx >= N or ny < 0 or ny >= N:
return False
snake_loc.append([ny, nx])
if [ny, nx] not in apple_loc:
snake_loc.popleft()
if [ny, nx] in apple_loc:
apple_idx = apple_loc.index([ny, nx])
for i in range(2):
apple_loc[apple_idx][i] = -1
return True
def turn(point):
global direction
if point == 'D':
direction += 1
if direction == 4:
direction = 0
if point == 'L':
direction -= 1
if direction == -1:
direction = 3
solve()
'알고리즘 & 코테' 카테고리의 다른 글
[BOJ] 백준 2579 계단 오르기 Python (1) | 2024.01.09 |
---|---|
[BOJ] 백준 17298 오큰수 Python (1) | 2024.01.08 |
[BOJ] 백준 5430 AC Python (1) | 2024.01.08 |
[BOJ] 백준 2449 전구 Python (1) | 2024.01.06 |
[BOJ] 백준 3977 축구 전술 Python (0) | 2024.01.05 |
@Indigochi1d :: Indigochi1d's Commit Log
안녕하세요? 개발자입니다.