오늘의 인기 글
최근 글
최근 댓글
Today
Total
05-20 11:35
관리 메뉴

우노

[Implementation] 이코테 “뱀” Python 풀이 본문

Algorithm/Implementation

[Implementation] 이코테 “뱀” Python 풀이

운호(Noah) 2022. 9. 5. 17:54

문제

  • 'Dummy'라는 도스 게임이 있습니다.
  • 이 게임에는 뱀이 나와서 기어 다니는데, 사과를 먹으면 뱀 길이가 늘어납니다.
  • 뱀이 이리저리 기어 다니다가 벽 또는 자기 자신의 몸과 부딪히면 게임이 끝납니다.
  • 게임은 N x N 정사각 보드 위에서 진행되고, 몇몇 칸에는 사과가 놓여져 있습니다.
  • 보드의 상하좌우 끝에는 벽이 있습니다.
  • 게임을 시작할 때 뱀은 맨 위 맨 좌측에 위치하고 뱀의 길이는 1입니다.
  • 뱀은 처음에 오른쪽을 향합니다.
  • 뱀은 매 초마다 이동을 하는데 다음과 같은 규칙을 따릅니다.
    • 먼저 뱀은 몸길이를 늘려 머리를 다음 칸에 위치시킵니다.
    • 만약 이동한 칸에 사과가 있다면, 그 칸에 있던 사과가 없어지고 꼬리는 움직이지 않습니다.
    • 만약 이동한 칸에 사과가 없다면, 몸길이를 줄여서 꼬리가 위치한 칸을 비워줍니다.
    • 즉, 몸길이는 변하지 않습니다.
  • 사과의 위치와 뱀의 이동 경로가 주어질 때 이 게임이 몇 초에 끝나는지 계산하세요.

입력 조건

  • 첫째 줄에 보드의 크기 N이 주어집니다. (2<=N<=100)
  • 다음 줄에 사과의 개수 K가 주어집니다. (0<=K<=100)
  • 다음 K개의 줄에는 사과의 위치가 주어지는데, 첫 번째 정수는 행, 두 번째 정수는 열 위치를 의미합니다.
  • 사과의 위치는 모두 다르며, 맨 위 맨 좌측(1행 1열)에는 사과가 없습니다.
  • 다음 줄에는 뱀의 방향 변환 횟수 L이 주어집니다. (1<=L<=100)
  • 다음 L개의 줄에는 뱀의 방향 변환 정보가 주어지는데, 정수 X와 문자 C로 이루어져 있으며,
  • 게임 시작 시간으로부터 X초가 끝난 뒤에 왼쪽(C가 'L') 또는 오른쪽(C가 'D')으로 90도 방향을 회전시킨다는 뜻입니다.
  • X는 10,000 이하의 양의 정수이며, 방향 전환 정보는 X가 증가하는 순으로 주어집니다.

출력 조건

  • 첫째 줄에 게임이 몇 초에 끝나는지 출력합니다.

입력 예시

6
3
3 4
2 5
5 3
3
3 D
15 L
17 D
10
4
1 2
1 3
1 4
1 5
4
8 D
10 D
11 D
13 L
10
5
1 5
1 3
1 2
1 6
1 7
4
8 D
10 D
11 D
13 L

출력 예시

9
21
13

풀이

  • 뱀은 바라보고 있는 방향으로 직진함
  • 회전은 좌표 기반으로 오른쪽 또는 왼쪽으로 진행되므로, 오른쪽(동남서북) 또는 왼쪽(동북서남)에 따른 이동 배열을 별도로 저장해두는게 편리함
  • 뱀의 위치는 board에 별도로 표시하고, 머리부터 꼬리까지의 위치는 snake 리스트에 순서대로 저장
  • 다음 이동 위치에 사과가 있을 경우, snake 리스트에 뱀의 머리 위치만 추가하고,
  • 다음 이동 위치에 사과가 없을 경우, snake 리스트에 뱀의 머리 위치를 추가하고, 꼬리 위치를 제거하는 방식으로 진행

예제 코드

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

import sys

# 보드의 크기
n = int(sys.stdin.readline())

# 보드 생성
board = [[0]*n for _ in range(n)]

# 사과의 개수
k = int(sys.stdin.readline())
# 사과의 위치
for _ in range(k):
    i, j = map(int, sys.stdin.readline().split())
    board[i-1][j-1] = 1

# 뱀의 방향 변환 횟수
l = int(sys.stdin.readline())
# 뱀의 방향 변환 정보
rotate = []
for _ in range(l):
    x, c = sys.stdin.readline().split()
    rotate.append((int(x), c))

# 방향 전환 인덱스 (동남서북)
# 오른쪽 방향 전환 'D' 시 인덱스 증가, 왼쪽 방향 전환 'L' 시 인덱스 감소
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

def simulate():
    # 시작 위치
    i, j = 0, 0
    # 뱀의 시작 위치 저장
    board[i][j] = 2
    # 현재 방향
    dir = 0
    # 초과 시간
    time = 0
    # 뱀의 몸 위치를 저장
    snake = [(0,0)]

    while True:

        # 다음 위치
        new_x = i + dx[dir]
        new_y = j + dy[dir]

        # 다음 위치에 뱀이 벽에 부딪히거나, 뱀의 몸에 부딪히는지 확인
        if (0 > new_x or new_x >= n or 0 > new_y or new_y >= n or board[new_x][new_y] == 2 ):
            time += 1
            break

        # 다음 위치로 이동할 수 있다면
        else:
            # 다음 위치가 사과라면
            if (board[new_x][new_y] == 1):
                # 뱀 머리 위치 표시
                board[new_x][new_y] = 2
                # 뱀 머리 위치 저장
                snake.append((new_x, new_y))

            # 다음 위치가 사과가 아니라면
            else:
                # 뱀 머리 위치 표시
                snake.append((new_x, new_y))
                # 뱀 머리 위치 저장
                board[new_x][new_y] = 2
                # 뱀 꼬리 위치 저장 제거
                px, py = snake.pop(0)
                # 뱀 꼬리 위치 표시 제거
                board[px][py] = 0

        # 현재 위치 변경
        i, j = new_x, new_y
        # 시간 증가
        time += 1

        # 방향 전환이 남아있으며, 다음 차례가 방향 전환 시간이라면
        if (len(rotate) >= 1 and time == rotate[0][0]):
            # 오른쪽 방향 전환이라면
            if (rotate[0][1] == 'D'):
                dir = (dir + 1) % 4
            # 왼쪽 방향 전환이라면
            else:
                dir = (dir - 1) % 4

            #  방향 전환했으므로 리스트에서 제거
            rotate.pop(0)

    return time

print(simulate())

참고

  • 이것이 취업을 위한 코딩 테스트다. with python
Comments