728x90
반응형
전통적인 그리디 문제이다. 부분 최적해가 전체 최적해가 된다.
can_eat 함수의 슬라이싱 부분은, 투포인터나 슬라이딩 윈도우 성질도 띈다.
import sys
input = sys.stdin.readline
"""
N: 식탁의 길이
K: K 이하 거리 햄버거 먹기 가능
table: 사람과 햄버거의 위치
사람 기준 순서대로 왼쪽이든 오른쪽이든 가장 가까운거 먹으면 될거같은데..? 그리디?
K가 최대 10이니 가능할거같다. K <= N이었으면 힘들었을듯.
햄버거와 사람을 따로 보지 않고, 매핑되는 관계로 간주한다.
왼쪽부터 K범위를 순차 탐색하며, 매핑될 경우 두 요소를 방문처리한다.
"""
def can_eat(idx, K):
# 기준 (사람 또는 햄버거)
point = table[idx]
# idx 뒤로 K거리만큼 잘라낸다 (슬라이싱은 인덱스오류 안남)
sliced_table = table[idx + 1: idx + K + 1]
# 거리 내에 있는 햄버거/사람을 찾으면 방문 처리
for i in range(len(sliced_table)):
if point != sliced_table[i] and not visited[idx + 1 + i]:
visited[idx + 1 + i] = True
return True
return False
N, K = map(int, input().split())
table = list(input().strip())
visited = [False] * N
result = 0
for i in range(N):
# 아직 매칭되지 않은 사람/햄버거에 대해 진행
if not visited[i]:
visited[i] = True
if can_eat(i, K):
result += 1
print(result)
일단, 나는 사람(P)과 햄버거(H)를 매핑되는 관계로 간주하고 딱히 구분짓지 않았다.
그리고 visited 리스트를 사용해서 이미 매핑된 사람/햄버거는 방문처리하여 다시 탐색하지 않게 했다.
사람과 햄버거를 구분짓지 않으면, 왼쪽부터, 즉 0번 인덱스부터 차례로 기준점이 되는 것이 가능해진다.
그리고 각 기준점에서 K거리만큼의 범위만 확인하되, H라면 P를, P라면 H를 찾으면 된다. 요소는 H 또는 P 2개밖에 없기 때문에 != 연산을 사용하면 된다.
그리고 매핑될 때마다 result를 1씩 추가해 주면 정답을 도출할 수 있다.
시간 복잡도는 O(N)이고 정확히는 O(KN) 인데, K의 최대값이 몇이냐에 따라 복잡도가 많이 바뀐다.
이 문제에서 K는 최대 10이라, 정확히는 O(10N) 이라서 O(N)에 수렴하는데,
만약 K의 최대값이 N이었다면 O(N^2)이 되고 4억번 이상의 연산이 필요하여 문제 해결이 어려웠을 것이다.
한 번에 통과했다.
다른 사람들 제출 내역을 보니, 최근 제출 중에는 내 코드가 가장 빨랐다. 매우 기쁘다.
728x90
반응형
'Algorithm > Greedy' 카테고리의 다른 글
[백준 20310 / Python / 실버3] 타노스 (0) | 2025.07.04 |
---|---|
[Baekjoon 11000 / Python / 골드5] 강의실 배정 (0) | 2025.01.23 |
[Baekjoon 2138 / Python / 골드4] 전구와 스위치 (2) | 2024.09.26 |
[Baekjoon 1911 / Python / 골드5] 흙길 보수하기 (0) | 2024.08.19 |
[Baekjoon 7983 / Java / 골드5] 내일 할거야 (0) | 2024.05.06 |