새소식

반응형
코딩 테스트

[프로그래머스] 아이템 줍기

  • -
728x90
반응형

문제

  • 다각형 모양의 둘레를 따라 캐릭터가 이동할 때, 특정 위치의 아이템을 줍기 위해 이동해야 하는 가장 짧은 거리 찾기

  • 캐릭터의 위치 (cX, cY)와 아이템의 위치 (iX, iY)가 주어진다.
  • 1 <= 직사각형 개수 <= 4
  • 1 <= X, Y <= 50

 

풀이

  • 캐릭터가 움직일 수 있는 테두리선을 찾아야 한다.
    • 가로선으로 움직이는 경우와 세로선으로 움직이는 경우를 나눠서 표현한다.
    • 예를 들어 (1, 3) -> (1, 4) 는 (1, (3, 4)) 로 표현한다.
    • 직사각형의 테두리선을 추가하고, 직사각형 내부 선은 제거한다.
  • 캐릭터의 위치에서 상하좌우로 움직일 때의 최단거리 찾기 (BFS)
    • 테두리선을 따라 움직이기 때문에 가능한 방향은 항상 2개가 존재한다.
    • 따라서 방문 배열을 하나만 두고, 이미 움직인 곳인지 확인하도록 한다.

 

from collections import deque

answer = 1e9
def solution(rectangle, characterX, characterY, itemX, itemY):
    maps = set()
    # 직사각형 테두리선 추가하기
    for lx, ly, rx, ry in rectangle:
        for x in range(lx, rx):
            maps.add(((x, x+1), ly))
            maps.add(((x, x+1), ry))
                
        for y in range(ly, ry):
            maps.add((lx, (y, y+1)))
            maps.add((rx, (y, y+1)))
    
    # 직사각형 내부 선 제거하기 (겹치는 부분들)
    for lx, ly, rx, ry in rectangle:
        for x in range(lx+1, rx):
            for y in range(ly, ry):
                if (x, (y, y+1)) in maps :
                    maps.remove((x, (y, y+1)))
        for y in range(ly+1, ry):
            for x in range(lx, rx):
                if ((x, x+1), y) in maps :
                    maps.remove(((x, x+1), y))
    
    # 최단거리 찾기
    visited = dict(zip(maps, [False]*len(maps)))    # 방문 배열
    q = deque([(characterX, characterY, 0)])
    
    while q:
        x, y, cnt = q.popleft()

        if x == itemX and y == itemY :  # 아이템에 도달한 경우
            return cnt
        
        if ((x-1, x), y) in maps and not visited[((x-1, x), y)]:   # 좌
            q.append((x-1, y, cnt+1))
            visited[((x-1, x), y)] = True
        if ((x, x+1), y) in maps and not visited[((x, x+1), y)]:   # 우
            q.append((x+1, y, cnt+1))
            visited[((x, x+1), y)] = True
        if (x, (y, y+1)) in maps and not visited[(x, (y, y+1))]:   # 위
            q.append((x, y+1, cnt+1))
            visited[(x, (y, y+1))] = True
        if (x, (y-1, y)) in maps and not visited[(x, (y-1, y))]:   # 아래
            q.append((x, y-1, cnt+1))
            visited[(x, (y-1, y))] = True
                
    return answer

 

 

 

References

  • 프로그래머스 고득점Kit 아이템 줍기
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.