m1ndy5's coding blog

프로그래머스 경주로 건설 with Python 본문

알고리즘 with python/알고리즘 스터디

프로그래머스 경주로 건설 with Python

정민됴 2023. 12. 20. 11:43

https://school.programmers.co.kr/learn/courses/30/lessons/67259

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

단순 그리디처럼 보였지만 알고보니까 굉장한 반례가 숨어있던(?) 문제였다...

이 반례를 찾은 사람도 정말 대단하다ㅋㅋㅋㅋ

단순히 cost가 더 적은 애로 바꿔서 계산하면 될 줄 알았는데 방향을 틀면 600원이 추가되야되기 때문에 당장은 원래 방향인 애가 더 쌌는데 다음번에는 이전 애 방향으로 내려오는 게 더 쌀 수도 있던 문제였다.

  벽    1000  벽

900     ?      벽 (옆에서 오면 1000원, 위에서 오면 1100원 -> 여기서는 옆에서 온게 더 쌈)

  벽       ?      벽 (위에서 쭉 내려오면 1200원, 꺾어서오면 1600원 -> 여기서는 위에서 온게 더 쌈)

이렇게 교차점이 생길 때 가운데서 위방향으로 내려 온 애가 가운데서는 더 비쌌는데 밑에서는 더 싼 경우가 있더라 ㄷㄷ

따라서 어떤 방향에서 왔을 때가 가장 베스트인지 방향에 따라서도 값을 비교해야하는 문제였다... (체감 레벨 4는 되는듯.....)

from collections import deque

def solution(board):
    n = len(board)
    cost = [[[1e9] * n for _ in range(n)] for _ in range(4)] # 방향, 위치에 따른 비용 리스트
    dx, dy = [0, 1, 0, -1], [1, 0, -1, 0] # 동남서북
    queue = deque([])
    
    # 4 방향의 시작점 초기화
    for i in range(4):
        cost[i][0][0] = 0
        
    # 시작점 옆 100원 초기화
    if board[0][1] == 0:
        queue.append([0, 1, 0, 100])
        cost[0][0][1] = 100
    
    # 시작점 밑 100원 초기화
    if board[1][0] == 0:
        queue.append([1, 0, 1, 100])
        cost[1][1][0] = 100
    
    while queue:
        x, y, d, c = queue.popleft() # 위치, 방향, 비용
        # 동서남북 이동
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < n and 0 <= ny < n and not board[nx][ny]: # 이동 가능한 범위이며 빈칸인 경우
                new_cost = c + 100 if d == i else c + 600 # 같은 방향(ex. 오른쪽으로 가고 또 오른쪽으로 갈경우) 100 다른 방향 600
                if cost[i][nx][ny] > new_cost: # 기존 다음 위치 비용보다 더 작다면 비용 갱신
                    cost[i][nx][ny] = new_cost
                    queue.append([nx, ny, i, new_cost])  
                    
    
    # 4방향으로 온 거 다 비교해서 가장 작은 거
    return min([cost[i][-1][-1] for i in range(4)]) # 최소 비용

 

참고 : https://soohyun6879.tistory.com/258

 

[프로그래머스/Python] 경주로 건설

https://programmers.co.kr/learn/courses/30/lessons/67259 코딩테스트 연습 - 경주로 건설 [[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,0],[0,0,0,0,0,1,0,0],[0,0,0,0,1,0,0,0],[0,0,0,1,0,0,0,1],[0,0,1,0,0,0,1,0],[0,1,0,0,0,1,0,0],[1,0,0,0,0,0,0,0]] 3800 [[0,0,

soohyun6879.tistory.com