본문 바로가기

알고리즘

[baekjoon] 3190. 뱀


로직

1. 구현문제. 문제에서 하라는대로 그대로하면 되는데, 실제로 코드를 돌렸을 때 에러들이 많이 발견됨.(내 구현 능력부족)

 

코드

from collections import deque

N = int(input())
K = int(input())
board = [[0 for _ in range(N)] for _ in range(N)]

for k in range(K):
    x, y = map(int, input().split())
    board[x-1][y-1] = 1  # 사과1, 뱀2, 빈칸0

L = int(input())
change = {}
# 리스트가 아닌 dict로 하는 이유
# dict로 하면 밑에서 시간에 해당할 때 time이 change에 해당하는게 있다면 change_move함수를 써야하는데 이것을 관리하기가 힘들다.
# popleft해버리면 시간이 너무 더 쓰일것같고..
for l in range(L):
    time, dir = input().split()
    change[int(time)] = dir

near = (0, 1)
def change_move(near, direction):
    nx, ny = near
    if nx == 0:
        if direction == 'D':
            if ny > 0:
                return (1, 0)
            else:
                return (-1, 0)

        else:
            if ny > 0:
                return (-1, 0)
            else:
                return (1, 0)

    elif ny == 0:
        if direction == 'D':
            if nx > 0:
                return (0, -1)
            else:
                return (0, 1)

        else:
            if nx > 0:
                return (0, 1)
            else:
                return (0, -1)


time = 0
q = deque([[0, 0]])
board[0][0] = 2
x, y = 0, 0
# while q하면 이게 하나씩 움직이는게 아니라
# 뱀 길이가 2이상일 때 밖으로 하나라도 나가면 stop이 되어야하므로 while True:
while True:
    time += 1

    xi, yi = x + near[0], y + near[1]

    if 0 <= xi < N and 0 <= yi < N:

        # 사과O
        if board[xi][yi] == 1:
            board[xi][yi] = 2
            q.append([xi, yi])

        # 사과X -> 뱀이 지나가면 됨
        elif board[xi][yi] == 0:
            board[xi][yi] = 2
            q.append([xi, yi])
            # 꼬리를 빈칸으로 바꿔야한다. -> board[x][y]하면 바로 전 값이 변하는것이므로
            # 이때 popleft하면 error, pop하면 ok
            nx, ny = q.popleft()
            board[nx][ny] = 0

        # 자기 몸에 부딛히면
        elif board[xi][yi] == 2:
            break

        # x, y를 xi, yi로 갱신해줘야함
        # why? 나는 q에서 pop해서 x,y를 가지고온게 아니라 x, y = 0, 0이라고 지정해주었기 때문!
        x, y = xi, yi

        # 방향 바뀔때
        if time in change:
            # print(time)
            near = change_move(near, change[time])


    else:  # board벗어나면 stop!
        break

print(time)

 

주의할 점

1. ** 문제점 : while q를 하면 안됨

   ** 해결책 : while q하면 이게 하나씩 움직이는게 아니라, 뱀 길이가 2이상일 때 밖으로 하나라도 나가면 stop

                  되어야하므로 while True:

 

2. ** 문제점 : board[xi][yi]가 [0,1]은 갱신이 되고 그 이후로 갱신이 되지 않음

   ** 해결책1. : 보통 q에서 pop을 해서 x, y를 지정하는데, 이 문제에서는 x, y = 0, 0이라고 내가 지정했다.

                  이때, while True 안에 x, y = 0, 0을 적어놓음. 그러다보니까 while문이 돌때마다 0,0으로 초기화 됨,,

                  -> while문 밖에 x,y = 0,0을 두자

   ** 해결책2. : x, y xi, yi로 갱신해줘야함
                    why? 나는 q에서 pop해서 x,y를 가지고온게 아니라 x, y = 0, 0이라고 지정해주었기 때문!

 

3. ** 문제점 : 꼬리를 바꿔야한다

   ** 해결책 : 

       사과X -> 뱀이 지나가면 됨
       elif board[xi][yi] == 0:
           board[xi][yi] = 2

           q.append([xi, yi])
           # 꼬리를 빈칸으로 바꿔야한다. -> board[x][y]하면 바로 전 값이 변하는것이므로

              내가 위에서 append했기 때문에 뱀의 머리가 마지막, 꼬리가 앞에 있는것 -> popleft해야함

           nx, ny = q.popleft()
           board[nx][ny] = 0

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

[baekjoon] 14502. 연구소  (0) 2020.08.15
[programmers] 보석쇼핑  (0) 2020.08.13
[programmers] 카카오프렌즈 컬러링북  (0) 2020.08.11
[programmers] 가장 큰 수  (0) 2020.08.11
[programmers] 문자열 압축  (0) 2020.08.11