카테고리 없음

[백준] 뱀

꿈꿈개 2022. 9. 1. 00:51

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

 

3190번: 뱀

 'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임

www.acmicpc.net

문제

NxN 정사각 보드위에서 진행 되고, 몇몇 칸에는 사과가 놓여져 있다.

보드의 상하좌우 끝에는 벽이 있고, 게임이 시작할 때는 뱀은 맨 위 맨 좌측에 위치하고 뱀의 길이는 1이다.

뱀은 처음에 오른쪽을 향한다.

뱀은 매초 이동하는데 다음과 같은 규칙을 따른다

  • 먼저 뱀은 몸 길이를 늘려 머리를 다음 칸으로 위치시킴
  • 만약 이동한 칸에 사과가 있다면, 그 칸에 있던 사과가 없어지고 꼬리는 움직이지 않음
  • 이동한 칸에 사과가 없다면, 몸길이를 줄여서 꼬리가 위치한 칸을 비워줌. 몸길이는 변하지 않다는 것이다.

입력조건

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

해결 방법

구현 문제이다!

풀다가 유의깊게 봐야할 부분은 맨 위 맨 왼쪽을 1행 1열로 본다는 것과 방향을 바꿀떄는 주어진 시간이 끝난 뒤 방향이 바뀐다는 것을 조심해야한다.

난 이것 떄문에 시간을 엄청 잡아먹었다 ㅎㅎ

뱀이 움직이는 로직대로 그대로 구현하면 된다.

나같은 경우는 뱀에 해당하는 좌표를 큐 리스트에 삽입하여 머리 추가 꼬리 삭제를 하도록 구현하였다.

 

from collections import deque

n=int(input())
graph=[[0]*n for _ in range(n)]

#뱀에 해당하는 좌표 1로 설정 시작은 0,0에서 시작함
graph[0][0]=1
#뱀에 해당하는 좌표 큐에 넣어주기
snake=deque([[0,0]])

#사과가 있는 곳 값 2로 설정
apple_cnt=int(input())
for _ in range(apple_cnt) :
     row, col=map(int, input().split())
     #1행1열이 (0,0)인 것처럼 -1한 인덱스에 넣어주는 것 유의
     graph[row-1][col-1]=2

d=int(input())

#시간과 방향 저장할 리스트 설정
dlist=[]
for _ in range(d) :
    t,order=input().split()
    dlist.append([int(t), order])
#초기준으로 정렬
dlist=sorted(dlist, key=lambda x : x[0])
dlist=deque(dlist)
#시작 시간과 시작 좌표 초기화
time=0
x=0
y=0

#상하좌우로 방향 바꿀 값 저장하는 리스트 설정
nd=[[0,1],[1,0],[0,-1],[-1,0]]

#초기는 오른쪽으로 움직임
direct=0

while True :
    time+=1
    
    #현재 시간의 방향대로 x와 y 좌표 이동
    nx=nd[direct][0]
    ny=nd[direct][1]

    x=x+nx
    y=y+ny
    #x와 y가 범위를 벗어날 때, 해당 위치가 뱀일때
    if x<0 or y<0 or x>n-1 or y>n-1  or graph[x][y]==1:
        break
    #사과를 만났을 때
    if graph[x][y]==2 :
        graph[x][y]=1
        snake.append([x,y])
    #사과도 벽도 뱀도 아닐떄 
    elif graph[x][y]==0 :
    	#꼬리 자르기
        sx, sy=snake.popleft()
        graph[sx][sy]=0
        #해당 좌표 뱀으로 설정
        graph[x][y]=1
        snake.append([x,y])
    #아직 처리하지 못한 방향 전환 명령이 있을 때
    if dlist:
        if time in dlist[0] :
            t, o=dlist.popleft()
            #오른쪽으로 회전
            if o=="D":
                direct+=1
            #왼쪽으로 회전
            elif o=="L" :
                direct-=1
    #dlist의 범위를 넘어서면 director 0으로 초기화
    if direct>=4 or direct<=-4 :
        direct=0

print(time)