문제
- 마름모 모양으로 되어 있는 부분의 사과만 수확한 경우 총 몇 개의 사과를 딸 수 있는지 구해라
- 칸들 안에 들어있는 해당 숫자는 수확량이다.
문제 풀이
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
을 사용한 최단거리를 구하는 문제입니다 또한 이 문제의 정확한 명칭은 다익스트라 알고리즘
이라 합니다.