파이썬으로 부시자! Python with Coreenee

BAEKJOON 3190

문제

스크린샷 2020-05-01 오후 11 00 35

입력

스크린샷 2020-05-01 오후 11 00 42


나의 처음 코드

문제에 글이 너무 많으면 풀기 싫어진다,,, 하지만! 유투브에서 Dummy게임 관련한 비슷한 게임을 본적이 있어서 쉽게 이해할 수 있었다. 즉, 지렁이가 있는데 사과를 먹으면 길이가 1만큼 커지고, 먹지 않으면 안 커진다는 것이다. 단, 벽에 부딪히거나 본인 몸에 부딪히면 게임은 종료가 된다. 우리가 구해야하는 값은 게임이 몇 초에 끝나는 것인가이다. 다행이 모든 케이스를 살펴보지 않아도 되는 것은, 몇 초일때 어디로 가라는 명령이 있기 때문이다. 명령을 받기 전까지는 쭈욱! 직진을 하면 되는 것이다.
내가 푼 방식은 다음과 같다. 사과좌표를 따로 저장한다. 하지만 저장하는 자료구조는 dict로 먹었는지/안먹었는지 구별할 것이다. 명령 또한 저장을 해줄 것인데, 이 또한 dict로 초마다 명령을 쉽게쉽게 찾을 수 있게 할 것이다. 나머지는 간단하다. 머리좌표를 옮긴다. 사과다(꼬리를 그대로 둔다)/사과가 아니다(꼬리를 자른다). 나는 꼬리를 찾기 편하게 하기 위해서 매초 직진할 때, 그 때의 초(sec)으로 map에 저장을 했다. 그러면 지금 꼬리가 잘리고 다음 꼬리가 될 친구를 쉽게 찾을 수 있기 때문이다. 아니면 좌표에 동서남북 방향을 숫자로 정해줘서 저장을 해줘도 된다. 코드는 다음과 같다!

#사과 == 길이 + 1
#벽 or 본인몸 == die
#init = 길이(1), (0,0), 오른쪽향함

#행열
N = int(input())
#사과 관련
numOfapple = int(input())
apple_coord = {}
for _ in range(numOfapple):
    coord = tuple(map(int, input().split()))
    if coord not in apple_coord:
        apple_coord[coord] = 1
#방향 관련
numOfdir = int(input())
dir_info = {}
for _ in range(numOfdir):
    inf = list(map(str, input().split()))
    dir_info[inf[0]] = inf[1] 
#방향 진행 리스트
#오른 아래 왼 위
ud_list = [0, 1, 0, -1]
rl_list = [1, 0, -1, 0]
#현재 몸이 깔고있는 좌표
on_the_map = [[0] * (N+1) for _ in range(N+1)]


def solution(head, tail, way):
    second = 0
    on_the_map[head[0]][head[1]] = second + 1
    
    while True:
        tmp_x = head[0] + ud_list[way]
        tmp_y = head[1] + rl_list[way]
        
        #벽에 부딪혔을 때
        if tmp_x <= 0 or tmp_y <=0 or tmp_x > N or tmp_y > N:
            second += 1
            break
    
        #자기 몸에 부딪혔을 때
        if on_the_map[tmp_x][tmp_y] > 0:
            second += 1
            break
        
        #사과를 먹었을 때
        if (tmp_x, tmp_y) in apple_coord and apple_coord[(tmp_x, tmp_y)] == 1:
            second += 1 #1초 지남
            on_the_map[tmp_x][tmp_y] = second + 1 #다음 꼬리 알기 쉽게 하기위해 초로 저장
            apple_coord[(tmp_x, tmp_y)] = 0 #사과 먹었으니깐 비활성화
            #머리 변경           
            head = [tmp_x, tmp_y]
        #사과를 먹지 않았을 때
        else:
            second += 1 #1초 지남
            tail_val = on_the_map[tail[0]][tail[1]] #현재 꼬리가 가지고 있는 초(second)
            ######################################
            #이거 포문 다음으로 써서 틀렸음.
            on_the_map[tmp_x][tmp_y] = second + 1
             ####################################
            #다음 꼬리 찾기
            for i in range(4):
                tail_tmp_x = tail[0] + ud_list[i]
                tail_tmp_y = tail[1] + rl_list[i]
                if 0 < tail_tmp_x <= N and 0 < tail_tmp_y <= N and on_the_map[tail_tmp_x][tail_tmp_y] == tail_val + 1:
                    on_the_map[tail[0]][tail[1]] = 0 #꼬리 비활성화 
                    tail = [tail_tmp_x, tail_tmp_y]
                    break             
            #머리 변경           
            head = [tmp_x, tmp_y]

        #방햠 설정
        if str(second) in dir_info:
            if dir_info[str(second)] == 'D':
                way += 1
                if way >= 4:
                    way = 0
            else:
                way -= 1
                if way < 0:
                    way = 3
    return int(second)


print(solution([1,1], [1,1], 0))

사과를 먹지 않았을 때, 머리를 먼저 움직여주지 않아서 틀렸습니다 가 떴다. 항상 일반화된 방향으로 코딩을 해야함을 다시 한번 느꼈다. 그리고 머리로 알고리즘 돌리는 것보다, 한 번 노트에 쓰면서 하면 예외도 쉽게 잡을 수 있다.!!!!!!!