chldkato

백준 3190 뱀 (파이썬) 본문

백준

백준 3190 뱀 (파이썬)

chldkato 2020. 4. 19. 16:44

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

 

3190번: 뱀

문제  'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임은 NxN 정사각 보드위에서 진행되고, 몇몇 칸에는 사과가 놓여져 있다. 보드의 상하좌우 끝에 벽이 있다. 게임이 시작할때 뱀은 맨위 맨좌측에 위치하고 뱀의 길이는 1 이다. 뱀은 처음에 오른쪽을 향한다. 뱀은 매 초마다 이동을 하는데 다음과 같은 규칙을 따

www.acmicpc.net

1. 리스트 rotate에 몇 초에 어느방향으로 회전할 지 저장한다

2. roate 안에 명령을 하나씩 꺼내서 이동한다

   뱀이 이동을 시작한 시간이 기준이기 때문에 rotate에서 꺼낸 시간을 이전에 꺼낸 시간을 빼준 만큼 이동한다

   bt는 rotate 함수의 이전 시간, snake 리스트는 뱀의 위치, head와 tail은 뱀의 머리와 꼬리 좌표다

3. 이동할 때 범위를 벗어나거나 뱀의 몸과 마주치면 이동 시간 + 1을 출력하고 종료한다

4. 뱀을 다음칸으로 이동시키고 머리 좌표를 갱신한다

   이 때 snake 리스트는 꼬리 좌표 갱신을 위해 이전 좌표 값에 + 1을 한다

5. 사과가 있으면 사과를 먹고 0으로 바꿔준다

6. 사과가 없으면 현재 꼬리 좌표를 불러와서 상하좌우에 차이값이 1인 좌표를 찾는다

   현재 꼬리 좌표는 0으로 바꿔주고 tail을 다음 꼬리 좌표로 갱신한다

7. 직선 이동을 마치면 회전을 해서 dir을 갱신한다

import sys

input = sys.stdin.readline
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

def move(x, y, t, r):
    global ans, dir, head, tail
    for i in range(t):
        nx = x + dx[dir]
        ny = y + dy[dir]
        if not 0 <= nx < n or not 0 <= ny < n:
            return 1
        if snake[nx][ny]:
            return 1

        snake[nx][ny] = snake[x][y] + 1
        head = [nx, ny]
        if a[nx][ny] == 1:
            a[nx][ny] = 0
        else:
            tx, ty = tail
            for j in range(4):
                ntx = tx + dx[j]
                nty = ty + dy[j]
                if not 0 <= ntx < n or not 0 <= nty < n:
                    continue
                if snake[ntx][nty] - snake[tx][ty] == 1:
                    snake[tx][ty] = 0
                    tail = [ntx, nty]
                    break

        x, y = nx, ny
        ans += 1

    dir = (dir + 1) % 4 if r == 'D' else (dir + 3) % 4


n = int(input())
k = int(input())
a = [[0 for _ in range(n)] for _ in range(n)]

for _ in range(k):
    x, y = map(int, input().split())
    a[x-1][y-1] = 1

rotate = []
l = int(input())
for _ in range(l):
    x, c = list(input().split())
    rotate.append([x, c])

bt, ans, dir, flag = 0, 0, 0, 0
snake = [[0 for _ in range(n)] for _ in range(n)]
snake[0][0] = 1
head, tail = [0, 0], [0, 0]
for t, r in rotate:
    nt = int(t) - bt
    res = move(head[0], head[1], nt, r)
    if res:
        print(ans+1)
        flag = 1
        break
    bt = int(t)

if flag == 0:
    move(head[0], head[1], n, r)
    print(ans+1)

Comments