파이썬알고리즘/SW Expert Academy

[ SW Expert Academy / 1949 ] 등산로 조성

투굠이 2020. 1. 8. 23:18

1. 문제 이해

입력값:
N (3 이상 8 이하)
K (1 이상 5 이하)
1 이상 20 이하 정수 (N 줄에 걸쳐)

유의해야 할 점:
1. 가장 높은 봉우리에서 시작 (첫 시작이 정해져 있음)
2. 높은 지역에서 낮은 지역으로 4방향 (같거나 대각선 불가)
3. 딱 한 곳을 정해서 최대 K만큼 지형 깎기 가능

N :정사각형 지도의 한 변의 길이
K : 최대 공사 가능 깊이

출력 값:
 가장 긴 등산로의 길이

 

2. 문제 풀이 법

사용한 방법: DFS

1.가장 높은 봉우리의 높이를 구한다.
2. 가장 높은 봉우리(첫 시작이 됨)를 탐색하여 리스트(starts)로 저장한다.

starts의 각 start에 대해 DFS 함수를 실시한다.

인자 : x값, y값, 깎은 유무, 현재까지 등산로 길이

1. visited 체크 (왔던 길 다시 안 가려고)

2. 4방향 탐색

- 범위를 넘어간다면 리턴해준다
- visited가 체크되어있다면 넘어가 준다 ( 지나왔던 길 )
- 위에 해당되지 않은 지형의 높이를 구한다.

    1) 그 높이가 현재 높이보다 작을 경우 dfs (그 지형 위치, 지형 높이, 깎은 유무, 현재 등산로 길이 + 1 )

    2) elif 그 높이보다 크거나 같은데 깎은 적이 없는데 최대 깎은 길이가 현재 높이보다 작으면
        dfs(그 지형 위치, 지형 높이 -1, 깎았다, 현재 등산로 길이 + 1)

- visited 다시 0으로 바꿔주기 (다음에 영향 미치니까!! 조합 같은 느낌)

2)에 지형 높이 -1 하는 것이 중요한 것 같다

 

3. 어려웠던 점

1. VISITED가 왜 필요한지 몰라서 한참 헤맸다.
2. DFS의 인자가 뭐가 필요한지 많이 필요해도 되는지 잘 몰라서 헤맸다.
--> 많아도 되나???? 평 씨가 알려줄 듯

def dfs(x, y, h, flag, t_ans):
    global ans
    visited[y][x] = 1
 
    if ans < t_ans: # 결과 값 넣어주기
        ans = t_ans
 
    for k in range(4): # 4방향 탐색
        temp_x = x + dx[k]
        temp_y = y + dy[k]
 
        if temp_x < 0 or temp_x >= N or temp_y < 0 or temp_y >= N : # 범위체크
            continue
            
        if visited[temp_y][temp_x] == 1: # 방문체크
            continue
 
        temp_h = mountain[temp_y][temp_x]

        if h > temp_h:
            dfs(temp_x,temp_y, temp_h, flag, t_ans+1)
            visited[temp_y][temp_x] = 0 
        elif flag != 0:
            if mountain[temp_y][temp_x] - K < h:
                dfs(temp_x, temp_y, h-1, 0, t_ans+1)
                visited[temp_y][temp_x] = 0
 
T = int(input())
dx = [-1,1,0,0]
dy = [0,0,-1,1]
 
for tc in range(1,T+1):
    N, K = map(int,input().split())
    mountain = [list(map(int,input().split()))for _ in range(N)]
    ans = 0
    starts = [] # [[x,y]
 
    m_s = max(sum(mountain,[])) #최댓값
    for i in range(N):
        for j in range(N):
            if mountain[i][j] == m_s:
                starts.append([j,i])
 
    for start in starts:
        mx,my = start
        visited = [[0 for _ in range(N)] for _ in range(N)]
        dfs(mx, my, m_s, 1, 1)
 
    print('#{} {}'.format(tc,ans))

4. 배운 점

VISITED 체크하고 다시 0으로 되돌리는 위치

 

제 결과입니다.
문제풀기전 생각했던 풀이과정 입니다