반응형
등굣길
문제 설명
계속되는 폭우로 일부 지역이 물에 잠겼습니다. 물에 잠기지 않은 지역을 통해 학교를 가려고 합니다. 집에서 학교까지 가는 길은 m x n 크기의 격자모양으로 나타낼 수 있습니다.
아래 그림은 m = 4, n = 3 인 경우입니다.
가장 왼쪽 위, 즉 집이 있는 곳의 좌표는 (1, 1)로 나타내고 가장 오른쪽 아래, 즉 학교가 있는 곳의 좌표는 (m, n)으로 나타냅니다.
격자의 크기 m, n과 물이 잠긴 지역의 좌표를 담은 2차원 배열 puddles이 매개변수로 주어집니다. 오른쪽과 아래쪽으로만 움직여 집에서 학교까지 갈 수 있는 최단경로의 개수를 1,000,000,007로 나눈 나머지를 return 하도록 solution 함수를 작성해주세요.
제한사항
- 격자의 크기 m, n은 1 이상 100 이하인 자연수입니다.
- m과 n이 모두 1인 경우는 입력으로 주어지지 않습니다.
- 물에 잠긴 지역은 0개 이상 10개 이하입니다.
- 집과 학교가 물에 잠긴 경우는 입력으로 주어지지 않습니다.
입출력 예
m n puddles return 4 3 [[2, 2]] 4
문제 풀이
def solution(m, n, puddles):
answer = 0
mapp = [[0 for _ in range(m)] for _ in range(n)]
for i in range(len(puddles)):
mapp[puddles[i][1] - 1][puddles[i][0] - 1] = "@"
# print(mapp)
mapp[0][0] = 1
for j in range(m):
if mapp[0][j] != "@":
mapp[0][j] = 1
elif mapp[0][j] == "@":
for i in range(j + 1, m):
mapp[0][i] = "@"
break
for i in range(n):
if mapp[i][0] != "@":
mapp[i][0] = 1
elif mapp[i][0] == "@":
for j in range(i + 1, n):
mapp[j][0] = "@"
break
for i in range(1, n):
for j in range(1, m):
if mapp[i][j] != "@":
if j != 0 and mapp[i][j - 1] != "@":
mapp[i][j] = mapp[i][j - 1] % 1000000007 + mapp[i][j] % 1000000007
if i != 0 and mapp[i - 1][j] != "@":
mapp[i][j] = mapp[i - 1][j] % 1000000007 + mapp[i][j] % 1000000007
answer = mapp[-1][-1] % 1000000007
return answer
문제 해석
개인적으로 dp유형 중 유명한 문제라 생각합니다. 웅덩이가 맵의 끝자락에 있을경우 오른쪽 또는 아래쪽으로 이동을 하지 못합니다. 이에 따른 예외처리를 먼저 진행해줍니다. 이후 시작 좌표를 1로 설정을 하여 탐색을 하면 탐색하기 전 좌표를 더하도록 합니다. dp 특성상 100*100 size가 되면 이는 상당한 수를 포함하기 때문에 100000007로 나눠줍니다. 최종값만 나누기보다는 기존에 연산을 할때마다 특정 숫자를 나눠줌으로써 시간효율성을 증가시킵니다. 또한 물웅덩이의 좌표때문에 약간 시간이 걸렸는데 예를들어 물웅덩이의 좌표가 (1,2)면 해당 위의 그림에서 파란색 오른쪽이 아닌 파란색 아래쪽입니다. 이에따라 기존좌표 값을 y,x로 생각하여 푸시면 됩니다.
'Algorithm > programmers' 카테고리의 다른 글
프로그래머스 [level2] 2 x 타일링 - python3 (0) | 2023.08.25 |
---|---|
프로그래머스 [level3] [2019 카카오 개발자 겨울 인턴십]불량 사용자 - python3 (0) | 2023.08.22 |
프로그래머스 [level3] 단어 변환 - python3 (0) | 2023.08.10 |
프로그래머스 [level2] 숫자의 표현 - python3 (0) | 2023.08.04 |
프로그래머스 [level2] JadenCase 문자열 만들기 - python3 (0) | 2023.08.02 |