문제 설명


orders는 L개의 뱀의 방향 변환 정보를 담는 배열, snake는 뱀의 머리부터 꼬리까지의 좌표들, dir은 현재 뱀의 방향을 나타낸다. 함수의 인자로는 방향 변환 정보를 하나씩 받아온다. answer는 게임 시작으로부터 경과 시간을 나타낸다.

첫번째 경우로 뱀의 방향이 오른쪽(R)일 때 order[0]은 게임이 시작 시간으로부터의 경과 시간이므로 반복문을 order[0] - answer 만큼 돌린다. answer를 1 더한 후 뱀의 머리 부분을 이동시켜 해당 좌표로 이동할 수 있는지 확인한다. 총 2가지 경우의 수를 확인해야 하는데
1. 뱀의 머리가 보드를 넘어가는지
2. 뱀의 머리가 자신의 몸통에 닿는지
만약 오른쪽으로 한 칸 이동했을 때 보드를 넘어가면 finished를 True로 바꾼후 종료한다.

뱀의 머리가 자신의 몸통에 닿을 경우 뱀의 머리의 좌표가 snake 배열에 있다는 뜻이므로 snake 배열에 해당 좌표가 있는지 확인한다.

위 과정을 통과하면 뱀이 지나갈 수 있다는 뜻이므로 지나가는 지점에 사과가 있는지 확인하고 사과가 있으면 해당 지점에 사과가 없다고 표시한 후 snake 배열에 해당 지점을 맨 앞에 넣어준다. 해당 지점에 사과가 없으면 머리 좌표를 snake에 넣고 맨 뒤 꼬리 부분을 pop을 하여 길이를 그대로 맞춘다.

마지막으로 방향 변환 정보가 'D'면 현재 방향이 오른쪽(R)이었으므로 dir을 'D'로 바꾸어 뱀의 진행방향을 아래방향으로 바꾸어준다. 방향 변환 정보가 'L'이면 dir을 'U'으로 바꾼다.

위처럼 dir이 L(왼쪽),D(아래쪽),U(위쪽) 세 가지 경우 설정하면 된다.
모든 방향을 변환하고도 게임이 끝이 나지 않을 경우 즉 main 함수에서 반복문이 끝나고 finished가 아직 False일 경우 func 함수에 큰 값과 'F'를 넣어 해당 방향으로 쭉 진행하게 했다.

전체 코드
board = []
orders = []
snake = []
N = 0
answer = 0
dir = 'R'
finished = False
def func(order):
global dir
global board
global snake
global answer
global finished
if dir == 'R':
for i in range(order[0]-answer):
answer += 1
head_x = snake[0][0]
head_y = snake[0][1] + 1
if head_y > N:
finished = True
return
if [head_x,head_y] in snake:
finished = True
return
if board[head_x][head_y] == 1:
board[head_x][head_y] = 0
snake.insert(0,[head_x, head_y])
else:
snake.insert(0,[head_x, head_y])
snake.pop()
if order[1] == 'D':
dir = 'D'
elif order[1] == 'L':
dir = 'U'
elif dir == 'D':
for i in range(order[0]-answer):
answer += 1
head_x = snake[0][0] + 1
head_y = snake[0][1]
if head_x > N:
finished = True
return
if [head_x, head_y] in snake:
finished = True
return
if board[head_x][head_y] == 1:
board[head_x][head_y] = 0
snake.insert(0,[head_x, head_y])
else:
snake.insert(0,[head_x, head_y])
snake.pop()
if order[1] == 'D':
dir = 'L'
elif order[1] == 'L':
dir = 'R'
elif dir == 'L':
for i in range(order[0]-answer):
answer += 1
head_x = snake[0][0]
head_y = snake[0][1] - 1
if head_y < 1:
finished = True
return
if [head_x, head_y] in snake:
finished = True
return
if board[head_x][head_y] == 1:
board[head_x][head_y] = 0
snake.insert(0,[head_x, head_y])
else:
snake.insert(0,[head_x, head_y])
snake.pop()
if order[1] == 'D':
dir = 'U'
elif order[1] == 'L':
dir = 'D'
elif dir == 'U':
for i in range(order[0]-answer):
answer += 1
head_x = snake[0][0] - 1
head_y = snake[0][1]
if head_x < 1:
finished = True
return
if [head_x, head_y] in snake:
finished = True
return
if board[head_x][head_y] == 1:
board[head_x][head_y] = 0
snake.insert(0,[head_x, head_y])
else:
snake.insert(0,[head_x, head_y])
snake.pop()
if order[1] == 'D':
dir = 'R'
elif order[1] == 'L':
dir = 'L'
def main():
global board
global orders
global snake
global N
global answer
snake.append([1, 1])
N = int(input())
for i in range(N+1):
board.append([0]*(N+1))
K = int(input())
for i in range(K):
n,m = map(int,input().split())
board[n][m] = 1
L = int(input())
for i in range(L):
tmp = input().split()
order = [int(tmp[0]),tmp[1]]
func(order)
if finished:
break
if not finished:
func([10005,'F'])
print(answer)
return
if __name__ == "__main__":
main()
'코딩테스트 > 파이썬' 카테고리의 다른 글
[백준] 14503번 로봇 청소기 (0) | 2021.02.17 |
---|---|
백준 12891번 톱니바퀴 (0) | 2021.02.11 |
백준 11559번 Puyo Puyo (0) | 2021.02.09 |
백준 18808번 스티커 붙이기 (0) | 2021.02.09 |
백준 12100번 2048(Easy) (0) | 2021.02.07 |