[TIL/크래프톤 정글9기] 16일차(뱀)

blueprint·2025년 5월 27일

크래프톤정글9기

목록 보기
14/55

백준 뱀



백준 뱀 문제는 2차원 배열로 하지 않아도 큐를 활용해서 풀 수 있는 문제다

문제

  • N×N 정사각 보드 위에서 뱀이 이동하며 사과를 먹는 시뮬레이션 문제
  • 뱀은 머리를 이동시키고, 사과를 먹으면 몸이 길어짐. 안 먹으면 꼬리 자름
  • 방향 전환 정보에 따라 방향을 꺾어가며 이동함
  • 뱀이 벽에 부딪히거나 자기 몸에 부딪히면 게임 종료
  • 게임이 끝나는 시간을 출력

아이디어

구현 방식

  • 뱀의 몸을 deque으로 표현하여 양쪽에서 삽입/삭제
  • 매 시간마다 머리를 이동시키고, 사과 여부와 충돌 여부 체크
  • 방향 전환은 시간 기준으로 미리 입력받은 리스트를 따라 회전

중요 포인트

  • 뱀이 사과를 먹으면 꼬리 자르지 않음 → deque.popleft() 생략
  • 사과를 먹었으면 반드시 해당 좌표를 apple_coord에서 제거
  • current에 있는 좌표와 새 머리 위치를 비교하여 자충돌 여부를 판단
import sys
from collections import deque
input = sys.stdin.readline

n = int(input())
apple = int(input())
apple_coord = [tuple(map(int, input().split())) for _ in range(apple)]
l = int(input())
direction = [input().strip().split() for _ in range(l)]

current = deque([(1,1)])

dir = 0  # 0 오른쪽 방향, 1 아래, 2 왼쪽, 3 위
dx = [0, 1, 0, -1]  # 오른쪽, 아래, 왼쪽, 위 
dy = [1, 0, -1, 0]

time = 0
idx = 0

while True:
    time += 1

    head_x, head_y = current[-1]

    # 새로운 머리 위치 계산
    new_x = head_x + dx[dir]
    new_y = head_y + dy[dir]

    # 2. 충돌 체크 (범위를 벗어났을 때, 내 몸통에 닿았을 때)
    if new_x < 1 or new_x > n or new_y < 1 or new_y > n: # n 범위를 벗어나거나, 음수일 떄
        break
    if (new_x, new_y) in current:
        break

    # 3. 새 머리 추가
    current.append((new_x, new_y))

    # 4. 사과 체크
    if (new_x, new_y) in apple_coord:
        # 사과 먹음 → 꼬리 안 자름
        apple_coord.remove((new_x, new_y))
    else:
        # 사과 안 먹음 → 꼬리 자름
        current.popleft()
        
    # 5. 방향 전환 체크
    if idx < l and time == int(direction[idx][0]):
        if direction[idx][1] == 'D':
            dir = (dir + 1) % 4  # 오른쪽 회전
        else:  # 'L'
            dir = (dir - 1) % 4  # 왼쪽 회전
        idx += 1

print(time)
  • 사과를 먹었을 때 리스트에서 제거하는 걸 빼먹으면 같은 위치에서 무한히 사과를 먹는 오류 발생
  • apple_coord.remove()를 함으로써 해결

파이썬에서 음수 나눗셈과 나머지의 동작 방식

정수 나눗셈 연산자 요약

  • /: 실수 나눗셈
  • //: 정수 나눗셈 (몫)
  • %: 나머지

파이썬의 나머지 연산 %

파이썬에서 나머지는 다음 공식을 만족:

a == (a // b) * b + (a % b)

즉, 나머지 %의 결과는 나눗는 수 b의 부호를 따름

예제

print(7 % 3)     # 1
print(-7 % 3)    # 2
print(7 % -3)    # -2
print(-7 % -3)   # -1

각 예제의 계산 과정을 보면:

  • -7 // 3 == -3
    -3 * 3 = -9
    -7 - (-9) = 2-7 % 3 == 2

  • 7 // -3 == -3
    -3 * -3 = 9
    7 - 9 = -27 % -3 == -2

  • -7 // -3 == 2
    2 * -3 = -6
    -7 - (-6) = -1-7 % -3 == -1


다른 언어와의 차이

C나 Java에서는 %피제수 a의 부호를 따라감. 반면, 파이썬에서는 나눗는 수 b의 부호를 따라감.

C 언어와의 비교

printf("%d\n", -7 % 3);  // -1 (C)

파이썬

print(-7 % 3)  # 2 (Python)

이 차이를 이해하고 있어야 다중 언어를 사용할 때 오류를 피할 수 있음


실용 팁

  • 나머지를 항상 양수로 만들고 싶다면, abs(b)를 사용:
positive_mod = a % abs(b)
  • 음수 결과가 필요하면 상황에 맞게 a % b 또는 math.fmod(a, b) 사용 고려

결론

  • 파이썬의 % 연산자는 항상 나눗는 수 b의 부호를 따름.
  • a == (a // b) * b + (a % b)
  • C/Java와는 다른 동작을 하기 때문에 주의

2개의 댓글

comment-user-thumbnail
2025년 5월 27일

왕꿈틀이처럼 생겼당

1개의 답글