ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 3190번 뱀
    알고리즘 2023. 4. 13. 10:16
    728x90
    반응형
    SMALL

    문제 설명

    이번 문제는 Dummy라는 도스게임을 제작하는 문제입니다. N * N 정사각 보드위에서 뱀이 매 초마다 아래와 같은 규칙으로 움직이고 사과의 위치와 뱀의 이동경로가 주어질 때, 게임이 몇 초에 끝나는지 계산하는 문제입니다.

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

     

    문제 풀이

    0. 변수

    N=int(input()) # 보드의 크기
    K=int(input()) # 사과의 개수
    apples=[list(map(int,input().split())) for _ in range(K)] # 사과의 좌표
    L=int(input()) # 뱀의 방향 전환 횟수
    changes=[input().split() for _ in range(L)] # 뱀의 방향 전환 정보
    
    board=[[0 for _ in range(N+2)] for __ in range(N+2)] # 보드판
    # 0->빈 칸 1->사과 2->뱀
    
    head,tail=[1,1],[1,1] # 뱀의 머리와 꼬리 좌표
    curves=[] # 뱀의 몸통 중 구부러진 구간의 좌표
    time=0 현재 시간
    c_i=현재까지 방향전환 횟수
    direction=1 # 0:위 1:오 2:아 3:왼

    1. 머리 이동

    뱀이 이동하는 첫 번째 규칙은 우선 몸의 길이를 늘려 머리를 다음칸에 위치시키는 것입니다.

    현재 방향에 따라 머리를 이동시켜 줍니다.

    if direction==0:
        head[0]-=1
    elif direction==1:
        head[1]+=1
    elif direction==2:
        head[0]+=1
    else:
        head[1]-=1

     

    2. 머리가 벽이나 뱀의 몸통에 부딪히는지 확인

    이동한 머리의 위치가 이거나, 뱀의 몸통일 경우 그만합니다.

    if board[head[0]][head[1]]==2:
        break
    if not (0<head[0]<=N and 0<head[1]<=N):
        break

     

    3. 꼬리 이동

    만약 이동한 머리의 위치에 사과가 있을 경우 꼬리는 이동하지 않습니다.

     

    만약 이동한 머리의 위치가 빈 칸일 경우,

    우선 꼬리의 좌표는 보드칸에 0으로 표시해줍니다.

    현재 꼬리의 좌표가 curves의 첫 번째 원소와 같다면(꼬리가 뱀의 구부러진 구간에 도착했다면) curves의 첫 번째 원소를 pop시켜줍니다.

    if board[head[0]][head[1]]==0:
        board[tail[0]][tail[1]]=0
        if curves and tail[0]==curves[0][0] and tail[1]==curves[0][1]:
            curves.pop(0)

    그 다음, curves에 원소가 있다면, curves의 첫 번째 원소 좌표와 현재 꼬리의 좌표의 행과 열 중 같은 것을 찾습니다. 만약 행이 같다면 꼬리의 열 좌표를 curves의 첫 번째 원소의 열 쪽으로 한 칸 움직이고, 열이 같다면 꼬리의 행 좌표를 curves의 첫 번째 원소의 행 쪽으로 한칸 움직입니다.

    if board[head[0]][head[1]]==0:
        ...
    
        if curves:
            if curves[0][0]==tail[0]:
                tail[1]+= 1 if curves[0][1]>tail[1] else -1
            else:
                tail[0]+= 1 if  curves[0][0]>tail[0] else -1

    curves에 원소가 없다면, 현재 뱀의 몸에 구부러진 구간은 없고 일직선인 상태이므로 꼬리 좌표의 행과 열 중 머리 좌표와 다른 것을 머리 좌표쪽으로 이동시켜줍니다.

    if board[head[0]][head[1]]==0:
        if curves:
            ...
        else:
            if head[0]==tail[0]:
                tail[1]+= 1 if head[1]>tail[1] else -1
            else:
                tail[0]+= 1 if head[0]>tail[0] else -1

    해당 작업까지 끝났다면 뱀의 머리에 대한 좌표값을 board에 2로 표시합니다.

     

    4. 방향 전환

    그 다음 해당 초가 끝나기 전에 현재 changes[c_i][0]이 time과 같은지 확인합니다.

    changes[c_i][0]==time일 경우 changes[c_i][1]에 따라 방향을 바꿔줍니다.

    바뀐 방향 정보를 direction에 담아주고, 해당 구부러진 구간의 좌표curves에 append해줍니다.

    if c_i<L and changes[c_i][0]==str(time):
        if changes[c_i][1]=='L':
            direction= direction-1 if direction>0 else 3
        else:
            direction= (direction+1)%4
        curves.append([head[0],head[1]])
        c_i+=1

     

    위의 작업을 뱀의 머리가 벽이나 뱀의 몸통에 닿지 않을 동안 반복해줍니다.

     

     

    해결

    이번 문제도 구현 문제로 차근히 풀이해야되는 문제였습니다.

     

    문제 링크 : https://www.acmicpc.net/problem/3190

     

    3190번: 뱀

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

    www.acmicpc.net

    코드 링크 : https://github.com/beomseok37/baekjoon/blob/master/new!/3190.py

    반응형
    LIST

    '알고리즘' 카테고리의 다른 글

    백준 14499번 주사위 굴리기  (2) 2023.04.29
    백준 10021번 Watering the Fields  (0) 2023.04.14
    백준 13460 구슬 탈출 2  (0) 2023.04.12
    백준 25515번 트리 노드 합의 최대값  (0) 2023.04.03
    백준 20035번 이동하기5  (0) 2023.03.31

    댓글

Designed by Tistory.