-
[카카오] 블록 이동하기 ( 파이썬 )코딩 테스트/프로그래머스 2023. 6. 10. 19:58
문제 설명
https://school.programmers.co.kr/learn/courses/30/lessons/60063
문제 풀이
- visited는 딕셔너리로 선언해서 키 값에 sx,sy,ex,ey 방문한 것들을 넣어주고 최소로 도착하는 시간을 기록해둠
- 동,서,남,북으로 이동했을 시에는 sx,sy,ex,ey의 순서는 그대로 유지된다.
- 90도로 꺽을 시에 생기는 유의 사항들
- 도형이 누워있거나 세워져 있거나에 따라 변하는 점이 달라짐.
- 90도로 꺽을 때 위에 있는, 왼쪽에 있는 점이 sx,sy가 되므로 좌표 계산 후 이 점을 유의해서 sx,syex,ey를 재조정
- 꺽을 때 기준점과 변하는 점 사이의 있는 점이 벽인지 체크 해줘야 함
- 위의 유의사항들은 그림으로 그려보고 찾아봄. 세번째 사항인 사이에 있는 점을 체크하는 것도 좌표 계산 리스트에 같이 넣어서 후에 for문에서 계산하게 함
소스 코드
from collections import deque dir = [ [-1,0,-1,0], [1,0,1,0], [0,-1,0,-1], [0,1,0,1], ] #동서남북 #rot[0]은 도형이 누워있을때 변하는 점들. #rot[1]은 세워져 있을때 #각 요소 [4]~[7]은 사이에 있는 점이 벽인지 체크 하기 위해 넣어준 것들 rot = [[[0,0,-1,-1,0,0,-1,0],[0,0,1,-1,0,0,1,0],[-1,1,0,0,-1,0,0,0],[1,1,0,0,1,0,0,0]], [[0,0,-1,-1,0,0,0,-1],[0,0,-1,1,0,0,0,1],[1,-1,0,0,0,-1,0,0],[1,1,0,0,0,1,0,0]]] def solution(gr): n = len(gr) visited = {} visited[0,0,0,1] = 0 q= deque() q.append((0,0,0,1,0,0)) answer = int(1e9) while(q): sx,sy,ex,ey,dic,d = q.popleft() # dic => 0 가로, 1 세로 if [sx,sy]==[n-1,n-1] or [ex,ey]==[n-1,n-1]: answer = min(d,answer) continue for i in range(8): if i<4: nsx,nsy,nex,ney = sx+dir[i][0],sy+dir[i][1],ex+dir[i][2],ey+dir[i][3] if nsx<0 or nsy<0 or nex<0 or ney<0 or nsx>=n or nex>=n or nsy>=n or ney>=n: continue `if gr[nsx][nsy]==1 or gr[nex][ney]==1: continue if (nsx,nsy,nex,ney) not in visited or visited[nsx,nsy,nex,ney]>d+1: visited[nsx,nsy,nex,ney] = d+1 q.append((nsx,nsy,nex,ney,dic,d+1)) else: j=i-4 nsx,nsy,nex,ney = sx+rot[dic][j][0],sy+rot[dic][j][1],ex+rot[dic][j][2],ey+rot[dic][j][3] csx,csy,cex,cey = sx+rot[dic][j][4],sy+rot[dic][j][5],ex+rot[dic][j][6],ey+rot[dic][j][7] if nsx<0 or nsy<0 or nex<0 or ney<0 or nsx>=n or nex>=n or nsy>=n or ney>=n: continue if gr[nsx][nsy]==1 or gr[nex][ney]==1 or gr[csx][csy]==1 or gr[cex][cey]==1: continue ddd = 1 if dic==0 else 0 if j in [0,3]: # 변한 ex,ey가 원점에 더 가까워서 sx,sy가 되는 경우들임 if ((nex,ney,nsx,nsy) not in visited or visited[nex,ney,nsx,nsy]>d+1) : visited[nex,ney,nsx,nsy] = d +1 q.append((nex,ney,nsx,nsy,ddd,d+1)) else: if ((nsx,nsy,nex,ney) not in visited or visited[nsx,nsy,nex,ney]>d+1): visited[nsx,nsy,nex,ney] = d +1 q.append((nsx,nsy,nex,ney,ddd,d+1)) return answer print(solution([[0, 0, 0, 1, 1],[0, 0, 0, 1, 0],[0, 1, 0, 1, 1],[1, 1, 0, 0, 1],[0, 0, 0, 0, 0]]))
'코딩 테스트 > 프로그래머스' 카테고리의 다른 글
[최단거리] 순위 (1) 2023.10.05 [DFS/BFS] 아이템 줍기 (파이썬) - 진행 중 (1) 2023.06.13 [연습 문제] 숫자 타자 대회 ( 파이썬 ) (0) 2023.06.06 [탐색] 퍼즐 조각 채우기 (파이썬) (0) 2023.06.02 [탐색] 미로 탈출 명령어 ( 파이썬 ) (0) 2023.05.14