[BFS][2차원 리스트] - 사과나무

yeom yaloo·2022년 7월 30일
0

codingtest

목록 보기
4/4


문제

  • 마름모 모양으로 되어 있는 부분의 사과만 수확한 경우 총 몇 개의 사과를 딸 수 있는지 구해라
  • 칸들 안에 들어있는 해당 숫자는 수확량이다.

문제 풀이

from collections import deque

n = int(input())
a = [list(map(int,input().split())) for _ in range(n)]
sum_apple = a[n//2][n//2]
ch = [[0]*n for _ in range(n)]
ch[n//2][n//2] = 1
dx = [0,0,-1,1]
dy = [1,-1,0,0]
q = deque()
q.append((n//2, n//2))
L = 0

while True:
    size = len(q)
    if L == n//2:
        break
    else:
        for i in range(size):
            apple = q.popleft()
            for j in range(4):
                nx = apple[0] + dx[j]
                ny = apple[1] + dy[j]
                if ch[nx][ny] == 0:
                    q.append((nx,ny))
                    ch[nx][ny] = 1
                    sum_apple += a[nx][ny]
    L += 1
    
print(sum_apple)

  • 해당 문제는 정중앙부터 상하좌우를 둘러가며 n//2까지의 노드 Level을 확인해주는 작업을 진행하는 BFS 문제입니다.
  • BFS는 DFS와 다르게 해당 레벨의 노드와 제일 가까운 자식 노드를 모두 확인해준 뒤 다음 자식의 자식 노드를 확인합니다.
  • 이때 상하좌우를 사용하여 마름모 모양만 총 합에 더해주는 식의 진행을 하며 check를 위한 2차원 리스트 변수와 node Level 확인을 위한 변수 L을 사용하였습니다.
  • 이 문제는 2차원 리스트의 시작 범위와 끝 범위를 잘 맞춰주면 또 풀 수 있는 문제지만 BFS 연습을 위해 BFS로 풀이를 진행했습니다.
  • n//2 이전까지 노드레벨만 확인하는 이유는 위의 사진을 보면 알 수 있습니다. 상하좌우를 확인하기 때문에 해당 노드를 두 칸씩 확인하며 진행하기 때문입니다.

[본인의 지극히 개인적인 DFS BFS 문제 느낀점]

  • DFS, BFS는 트리나 그래프를 도는 문제이기 때문에 노드의 흐름을 생각하고 진행해야 합니다.
  • DFS는 깊이 우선 탐색이라는 이름에 맞게 가까운 노드의 자식 노드 또 그 노드의 자식노드 이런식으로 진행함을 유의하며 진행하고 stack 자료구조를 사용한다는 점을 잊지 않고 복기하며 풀어야 합니다.
  • BFS는 거리를 구하는 문제에 적합하며 distance를 따로 저장할 수 있는 변수를 선언하여 여기에 거리를 넣어주는 연습을 하는 것이 중요합니다. 이때 BFS는 queue라는 자료구조를 쓰고 파이썬에서는 deque를 사용해 문제를 푸는 것이 일반적입니다. 이는 다음과 같은 이유 때문입니다.
  • 리스트는 동적 배열로 구현되어 큐의 연산을 수행하기엔 효율적이지 않기 때문입니다. (popleft()와 appendleft()는 deque에서 지원합니다.)
  • BFS는 해당 노드에 가까운 자식 노드를 전부 확인하고 다음 자식노드를 확인하는 식이기에 거리를 구하는 문제에 적합합니다.
  • 이때 거리가 가중치가 있고 이 가중치가 음의 수가 아니라면 이는 heap을 사용한 최단거리를 구하는 문제입니다 또한 이 문제의 정확한 명칭은 다익스트라 알고리즘이라 합니다.
profile
즐겁고 괴로운 개발😎

0개의 댓글