문제풀이/프로그래머스

미로탈출 명령어(카카오) 문제풀이

soo-dal 2024. 3. 14. 23:00

문제 

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

 

프로그래머스

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

programmers.co.kr

 

 

문제 접근 방식

처음에 DFS로 순회하면서 d > l > r > u 순으로 탐색을 하면 되지 않을까 했는데 시간 초과 및 에러가 발생했다. dfs , bfs를 응용하여 로직을 추가해주려 했으나 뭔가 계속 엉망이 되어서 그만두고 다른 분의 코드를 참고했다. 

 

전체적인 방법은 BFS 처럼 큐를 활용하며, 이웃한 4곳의 정보를 모두 큐에 넣는 것이 아닌, d > l > r > u 순으로 탐색하며 가능한 것을 큐에 넣고 이후 방향은 pass하는 방식으로 구현했다. 또한 다음 장소를 큐에 넣을 때, 다음 장소로 마지막 지점을 갈 수 있는지 여부를 판단해서 가능한 것만 큐에 넣어주도록 했다. 구체적인 처리과정은 아래와 같다.

1. 시작점과 끝점의 맨하탄 거리를 구해서 도달할 수 있는지를 판단한다
    1.1. 맨하탄 거리가 k 보다 크거나, (맨하탄 거리-k)%2==1 이면 도달할 수 없다
    
2. 큐에 시작위치를 넣고 큐를 순회한다
    2.1. 큐에서 꺼낸 위치가 마지막 지점과 같고 (k-dist)%2==1이라면 impossible을 반환한다
    2.1. 마지막 지점과 같고 k==dist라면, 이동경로를 반환한다
    
    2.3. 현재 위치에서 다음에 이동할 위치를 선정한다( d > l > r> u 순으로 탐색)
        2.3.1. 다음위치가 범위 내에 존재하고, 맨하튼 거리+(dist+1)이 k 이하라면(도달할 수 있는 거리라면) 
              큐에 넣어주고 다음 위치로 이동한다.

 

 

코드

from collections import deque

def solution(n, m, x, y, r, c, k):

	# 끝점와 임의의점의 맨하탄 거리를 구하는 함수
    def manhattan(r1,c1):
        return abs(r1-(r-1))+abs(c1-(c-1))
	
    # 맨하탄 거리가 k 이상 -> 최단 경로로도 도달할 수 없다
    # %2 ==1 -> 갔던 곳을 다시 지나도 도달할 수 없는 곳
    if manhattan(x-1,y-1)>k or (manhattan(x-1,y-1)-k)%2==1:
        return "impossible"
    
    q=deque()
    q.append((x-1,y-1,0,""))
    d={(1,0):"d",(0,-1):"l",(0,1):"r",(-1,0):"u"}
    
    while q:
        cr,cc,dist,route=q.popleft()
     	
        # 마지막 지점과 같은데, %2==1이라면 어떻게서든 갈 수 없는 장소
        if (cr,cc)==(r-1,c-1) and (k-dist)%2==1:
            return "impossible"
        elif (cr,cc)==(r-1,c-1) and dist==k: # k 와 같다면 경로를 반환
            return route
            
        # d > l > r > u  순으로 순회하며 다음 장소를 구함.
        # 다음 장소가 범위 내에 존재하고, 거리 상으로도 가능한 위치라면 큐에 넣어주고 break
        for dr,dc in d: 
            nr,nc=cr+dr,cc+dc
            if 0<=nr<n and 0<=nc<m and manhattan(nr,nc)+(dist+1)<=k:
                q.append((nr,nc,dist+1,route+d[(dr,dc)]))
                break

 

 

회고

1. 다음 이동할 장소에 대해 맨하튼 거리로 미리 도달 가능한지 여부를 판단한다. 
   도달할 수 있는 것만을 큐에 넣는다.
2. 사전형으로 최소가 되는 경로로 끝점에 도달을 하도록하고, 도달 했을때 불가능한 경우를 if문으로 처리한다
3. 거리가 k 라면 경로를 반환하도록 하고, 그렇지 않은 경우는 계속해서 큐를 순회하도록한다.