Algorithm/Implementation

[백준 3190번] 뱀

킹우현 2023. 8. 6. 17:53
from collections import deque
n = int(input())
k = int(input())

area = [[0]*n for _ in range(n)]
direction_list = []

time = 0

for _ in range(k):
    r,c = map(int,input().split())
    area[r-1][c-1] = 1

l = int(input())

for _ in range(l):
    x, c = input().split()
    direction_list.append((int(x),c))

x, y = 0, 0

direction = "R"

tail = deque([(0,0)])

index = 0

while 1:
    
    area[x][y] = -1

    if time == direction_list[index][0]: # index에 해당하는 시간이 지났을 경우

        if direction_list[index][1] == "L": # 왼쪽으로 회전
            if direction == "R":
                direction = "U"
            elif direction == "L":
                direction = "D"
            elif direction == "U":
                direction = "L"
            elif direction == "D":
                direction = "R"

        elif direction_list[index][1] == "D": # 오른쪽으로 회전
            if direction == "R":
                direction = "D"
            elif direction == "L":
                direction = "U"
            elif direction == "U":
                direction = "R"
            elif direction == "D":
                direction = "L"
        if index + 1 < len(direction_list): 
            index += 1
    
    # 방향에 따른 다음 위치 설정
    if direction == "R":
        nx, ny = x, y + 1
    elif direction == "L":
        nx, ny = x, y - 1
    elif direction == "U":
        nx, ny = x - 1, y
    elif direction == "D":
        nx, ny = x + 1, y

    # 벽에 부딪히거나 자기자신의 몸과 부딪힌 경우 게임종료
    if nx < 0 or nx >= n or ny < 0 or ny >= n or area[nx][ny] == -1:
        time += 1
        break

    if tail and area[nx][ny] == 0: # 이동한 칸에 사과가 없는 경우
        tail_x, tail_y = tail.popleft()
        area[tail_x][tail_y] = 0 # 꼬리 비워주기

    tail.append((nx,ny))

    x = nx
    y = ny
    time += 1

print(time)

이번 문제는 주어진 규칙에 따라 보드 위에서 움직이는 뱀이 자기자신의 몸을 만나거나 벽에 부딪혀서 게임이 종료될 때까지 걸리는 시간을 구하는 문제이다.
 
특별한 알고리즘이 필요한 문제는 아니었지만, 복잡한 조건들로 인해 구현하는데 시간이 많이 걸렸다. (처음에 조건을 잘못 이해하고 한번 헤맸었는데, 앞으로는 문제를 풀기전에 조건을 확실하게 파악한 뒤에 구현을 해야겠다고 굳게 다짐했다 .. 🥲)
 
먼저 사과가 있는 자리를 1, 뱀의 머리부터 꼬리까지 차지하는 자리를 -1로 채우는 방식으로 코드를 작성하고 time이라는 변수를 선언해서 while문 안에서 계속 뱀을 이동시켜주는 방식으로 문제를 풀이하였다.
 
여기서 중요했던 것은 꼬리의 위치를 기억하며 해당 자리를 비워주어야 하는데, 이를 위해서 queue 자료구조를 사용하였다. (deque 라이브러리) ⭐️
 
이번 문제를 풀면서 다음과 같은 점들을 느낄 수 있었다.

  1. 2차원 배열을 디버깅할 때는 행 단위로 print 하면 더 수월하게 과정을 체크할 수 있다.
  2. 변수명이 겹치도록 작성하면 예상치 못한 index 에러가 발생할 수 있으니 조심하자.
  3. 빠르게 문제를 읽고 곧바로 푸는 것보다 문제를 정확하게 이해하고 문제를 푸는게 시간이 더 절약된다. 꼭 문제를 확실하게 이해하고 구현에 들어가자. ⭐️⭐️