LastMod:

Day 14 : 작은 노드

해당 문제는 그래프와 노드, 간선에 대한 개념이 필요한 문제입니다. 현재 위치한 노드에서 다른 노드로 이동하는 개념이 필요합니다. 신규 제작 문제입니다.

문제 및 입출력 조건은 다음과 같다. Day14문제 입출력 예제는 다음과 같다. Day14예제

지금까지의 행렬 형태의 그래프 탐색 문제와는 달리, 진짜 양방향 그래프를 탐색하는 문제가 나왔다.

import sys, heapq
input = sys.stdin.readline

n, m, prev = map(int, input().split())
graph = [[] for _ in range(n + 1)]
visited = [False] * 2001
for _ in range(m):
    s, e = map(int, input().split())
    heapq.heappush(graph[s], e)
    heapq.heappush(graph[e], s)

visited[prev] = True
while True:
    if len(graph[prev]) == 0:
        print(sum(visited), prev)
        break
    curr = heapq.heappop(graph[prev])
    if visited[curr]:
        continue
    visited[curr] = True
    prev = curr

최대 노드 개수가 2천개이고, 간선 개수가 20만개 (양방향이니까 40만개를 저장해야 한다.) 이므로 인접행렬 방식으로 저장하면 메모리가 터진다. 방문할 수 있는 노드 중 번호가 가장 작은 노드로 이동한다는 조건 때문에 최소 힙을 이용하였다. 물론 입력을 모두 받은 다음, 노드를 돌면서 sort()를 사용해도 된다. 노드의 방문 여부만 잘 체크하면서 이동한다면 그리 어렵지는 않은 문제이다.

Day 15 : 과일 구매

해당 문제는 그리디의 응용문제입니다. 현재 상태에서 최고의 선택을 찾아야 합니다. 국비 교육 적성고사 변형 문제입니다.

문제 및 입출력 조건은 다음과 같다. Day15문제1 Day15문제2 입출력 예제는 다음과 같다. Day15예제

당황스럽게 갑자기 그리디 문제가 나와버렸다. 배낭 문제와 비슷하게 생겼지만, 과일을 조각낼 수 있다는 점에서 다르다.

import sys
input = sys.stdin.readline

fruits = []
n, k = map(int, input().split())
for _ in range(n):
    fruit = tuple(map(int, input().split()))
    fruits.append((fruit[1] // fruit[0], fruit[0], fruit[1]))
fruits.sort(reverse=True)

answer = 0
for part, price, fullness in fruits:
    if k > price:
        k -= price
        answer += fullness
    else:
        answer += (part * k)
        break

print(answer)

그리디는 앞선 포스팅에서 말했듯, 현재 상황에서 가장 좋은 것만을 골라 나아가는 알고리즘이다. 포만감이 가장 높아야 하므로, 조각 당 포만감이 가장 높은 과일을 고르는 것이 적합하다. 따라서 입력을 받을 때에 조각 당 포만감을 같이 구해서 그것을 기준으로 정렬 시켜놓고, 가지고 있는 돈에 맞추어 포만감을 구하면 된다. 과일 조각의 개수는 해당 과일의 가격에 달려있다는 것을 주의해야 한다.

3주차 후기

뭔가 그래프 탐색 문제가 더 많았던 것 같다. 다음주엔 도대체 뭘 내려고…? 메모리/시간 제한을 안써놓는게 좀 아쉽다. 시간 제한은 생각보다 널널한 것 같아서 그러려니 하는데, 12일차 문제에서 재귀 풀이를 막은 건 어이가 없다. 런타임 에러 로그도 안보이는데, 최소한 메모리 제한이라도 표기를 해놨으면 삽질하는 시간이 줄었을 것이다. 그래도 매번 공식 해설지를 제공해주는 것은 좋은 것 같다.

Leave a comment