백준 3190 - 파이썬

구기성·2023년 1월 3일
0

알고리즘

목록 보기
9/31

이 문제는 단순 구현문제이다. 문제가 좀 길지만 요약하자면 다음과 같다.

뱀의 이동 로직
1. 뱀이 이동하는 곳에 사과가 있다면, 사과가 사라지고 뱀의 꼬리는 그 자리에 있고 몸만 이동한다.
2. 뱀이 이동하는 곳에 사과가 없다면, 뱀의 머리와 꼬리가 함께 이동한다.

뱀이 움직임을 멈추는 조건
1. 뱀의 머리가 벽을 뚫는 경우
2. 뱀의 머리가 자신의 몸과 닿는 경우

추가로 뱀은 방향 전환을 할 수 있다.
처음에는 동쪽으로 이동을 하고 L이면 반시계방향으로 방향 전환, R이면 시계방향으로 방향 전환을 한다.

이때 뱀이 몇초후에 움직임을 멈추는지 계산을 하면 된다.
하나씩 문제를 로직을 생각하면서 진행하면 된다.
내가 작성한 코드는 아래와 같다.
코드의 주석을 보면 잘 이해를 할 수 있을 것이다.

import sys

N = int(sys.stdin.readline().strip())
K = int(sys.stdin.readline().strip())
array = [[0] * (N + 1) for _ in range(N + 1)]
for i in range(K):
    x, y = map(int, sys.stdin.readline().split())
    array[x][y] = 1
L = int(sys.stdin.readline().strip())
rotate = []
for i in range(L):
    x, y = map(str, sys.stdin.readline().split())
    rotate.append((int(x), y))

dx = [0, -1, 0, 1]
dy = [1, 0, -1, 0]
direction = 0 # 0은 동, 1은 북, 2는 서, 3은 남

x, y = 1, 1  # 초기 위치 저장
snakeBody = [(x, y)]  # 뱀 몸이 있는 위치 저장
time = 0  # 시간 저장

while True:
    # 현재 보고 있는 뱡향을 토대로 이동
    nx = x + dx[direction]
    ny = y + dy[direction]

    # 벽과 부딪힌 경우
    if nx < 1 or nx > N or ny < 1 or ny > N:
        time += 1
        break

    # 뱀의 몸과 부딪힌 경우
    if (nx, ny) in snakeBody:
        time += 1
        break

    if array[nx][ny] != 1:  # 사과가 아니라면 뱀 몸의 맨 처음 위치 제거
        snakeBody.pop(0)
    else:  # 사과라면 사과를 없애줌
        array[nx][ny] = 0

    snakeBody.append((nx, ny))  # 뱀의 몸 추가
    time += 1  # 시간 증가
    x, y = nx, ny  # x, y 최신화

    # 시간이 회전할 시간인지 체크
    for item in rotate:
        if time == item[0]:  # 만약에 회전할 시간이라면
            # L인 경우 반시계 방향
            if item[1] == 'L':
                if direction + 1 > 3:
                    direction = 0
                else:
                    direction += 1

            # D인 경우 시계 방향
            elif item[1] == 'D':
                if direction - 1 < 0:
                    direction = 3
                else:
                    direction -= 1
            break

print(time)

여기서 반복문 탈출 로직을 위해 뱀의 몸에 해당하는 배열을 잘 저장해야한다.

0개의 댓글