Algorithm/백준

[Python] 3190 뱀

내영잉 2023. 1. 18. 21:15

1. 문제 📚

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

2. 입출력 예 📋

3. 알고리즘 ✅

처음에 문제를 이해하는 데만 오래걸렸다;; 

초기 시작을 (0, 0)으로 두고 1초라고 둬야한다

보기 쉽게 $을 뱀 @ 을 사과라고 뒀다

 

예제1을 출력해보면 

time:  1 direction:  Right
$ . . . . .
. . . . @ .
. . . @ . .
. . . . . .
. . @ . . .
. . . . . .
time:  2 direction:  Right
. $ . . . .
. . . . @ .
. . . @ . .
. . . . . .
. . @ . . .
. . . . . .
time:  3 direction:  Right
. . $ . . .
. . . . @ .
. . . @ . .
. . . . . .
. . @ . . .
. . . . . .
time:  4 direction:  Down
. . . $ . .
. . . . @ .
. . . @ . .
. . . . . .
. . @ . . .
. . . . . .
time:  5 direction:  Down
. . . . . .
. . . $ @ .
. . . @ . .
. . . . . .
. . @ . . .
. . . . . .
time:  6 direction:  Down
. . . . . .
. . . $ @ .
. . . $ . .
. . . . . .
. . @ . . .
. . . . . .
time:  7 direction:  Down
. . . . . .
. . . . @ .
. . . $ . .
. . . $ . .
. . @ . . .
. . . . . .
time:  8 direction:  Down
. . . . . .
. . . . @ .
. . . . . .
. . . $ . .
. . @ $ . .
. . . . . .
time:  9 direction:  Down
. . . . . .
. . . . @ .
. . . . . .
. . . . . .
. . @ $ . .
. . . $ . .

뱀의 머리나 몸이 벽에 닿는 순간 멈춰야한다 

 

3가지의 조건을 따라

1. 사과를 먹으면 뱀의 길이가 늘어나야하기 때문에 뱀의 길이를 queue라고 생각하고

2. 사과가 없으면 다음칸으로 전진하고 꼬리를 원래의 값으로 돌려주기

3. 그 이외의 값(뱀의 몸이 닿는 순간) 멈추기

 

또한 방향설정이 조건에 있기 때문에 L, D 조건에 따라 방향을 바꿔줘야한다

4. 소스코드 💻

import sys
from collections import deque, defaultdict

input = sys.stdin.readline

N = int(input().strip())
K = int(input().strip())

board = [[0 for _ in range(N)] for _ in range(N)]

queue = deque([])
queue.append([0, 0])

# 사과
for i in range(K):
    x, y = map(int, input().strip().split())
    board[x - 1][y - 1] = 2

changeDir = defaultdict(str)
L = int(input().strip())

for i in range(L):
    x, c = input().strip().split()
    changeDir[int(x)] = c

x, y = 0, 0
# 뱀 초기 상태
board[x][y] = 1
time = 0
direction = 0

# 현재방향
now = 'Right'

def go(dir):
    global time
    global changeDir
    global now

    if time in changeDir:
        if dir == 'Right':
            if changeDir[time] == 'L':
                nx, ny = x - 1, y
                now = 'Up'
            elif changeDir[time] == 'D':
                nx, ny = x + 1, y
                now = 'Down'
        elif dir == 'Down':
            if changeDir[time] == 'L':
                nx, ny = x, y + 1
                now = 'Right'
            elif changeDir[time] == 'D':
                nx, ny = x, y - 1
                now = 'Left'
        elif dir == 'Left':
            if changeDir[time] == 'L':
                nx, ny = x + 1, y
                now = 'Down'
            elif changeDir[time] == 'D':
                nx, ny = x - 1, y
                now = 'Up'
        elif dir == 'Up':
            if changeDir[time] == 'L':
                nx, ny = x, y - 1 # 수정
                now = 'Left'
            elif changeDir[time] == 'D':
                nx, ny = x, y + 1
                now = 'Right'
    else:
        if dir == 'Right':
            nx, ny = x, y + 1
        elif dir == 'Down':
            nx, ny = x + 1, y
        elif dir == 'Left':
            nx, ny = x, y - 1
        elif dir == 'Up':
            nx, ny = x - 1, y

    return nx, ny

while True:
    x, y = go(now)
    time += 1

    if x < 0 or x >= N or y < 0 or y >= N:
        break

    # 사과 존재
    if board[x][y] == 2:
        # 사과 먹음처리
        board[x][y] = 1
        queue.append([x, y])
    # 전진
    elif board[x][y] == 0:
        # 뱀 이동
        board[x][y] = 1
        queue.append([x, y])

        # 뱀 꼬리 가져오기
        px, py = queue.popleft()
        board[px][py] = 0
    # 뱀이 자기 몸에 닿는 순간
    else:
        break

print(time)

다른 사람들 코드보니 방향 분기를 아래와 같이 더 간편하게 짰다 ^^ ; ;

dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

def turn(alpha):
    global direction
    if alpha == 'L':
        direction = (direction - 1) % 4
    else:
        direction = (direction + 1) % 4
        
while True:
    cnt += 1
    x += dx[direction]
    y += dy[direction]
    """
    이하생략
    """

방향 조건이 조금 헷갈려서 6시간 동안 삽질했다 

 

예를들어 나는 계속 오른쪽 방향 + L (왼쪽)  = 아래쪽이라고 생각했다 ;;

방향이 왼쪽으로 가도록 돌리니까 아래쪽나오길래 계속 그렇게 로직을 짜서 답이 안나왔었다

오른쪽방향 + L (왼쪽) = 위쪽 방향이다.

L(반시계방향), D(시계방향)으로 생각해야됐었다

 

앞으로는 조건을 더 신경써야겠다 〰️