Programming/백준
백준 2015 - 수들의 합 4 (파이썬)
pental
2025. 2. 24. 19:58
분류 : 누적합
링크 : https://www.acmicpc.net/problem/2015
풀이
부분합을 활용하여 특정 구간 합이 K가 되는 경우의 수를 찾는 문제이다.
단순한 방법으로는 O(N^2) 시간 복잡도로 모든 구간을 확인 할 수 있지만, 주어진 N의 최대값이 200,000 이므로, 이는 비효율적인 방법이다.
따라서, 누적합과 해시맵을 활용하여 O(N)으로 해결해야한다.
psum = [0] * N
psum[0] = A[0]
for i in range(1, N) :
psum[i] = psum[i - 1] + A[i]
- psum[i] 는 A[0] 부터 A[i] 까지의 합을 저장하는 누적합 배열이다.
- psum[i] = psum[i - 1] + A[i]를 이용하여 이전 누적합에 현재 값을 다하는 방식으로 누적합을 구한다.
- 이과정은 O(N)에 수행된다.
for i in range(N) :
goal = psum[i] - K
if goal == 0:
answer += 1
if goal in count :
answer += count[goal]
if psum[i] not in count :
count[psum[i]] = 0
count[psum[i]] += 1
- goal = psum[i] - K
- psum[j] - psum[i-1] = K 를 만족하는 j를 찾기 위해 변형하면psum[i-1] = psum[j] - K 가 된다.
- 즉, goal = psum[i] - K 가 과거의 누적합 중에 존재하는지 찾으면 된다.
- if goal == 0:
- psum[i] == K 라면 0부터 i까지의 부분합이 K인 경우 이므로 answer를 증가시킨다.
- if goal in count:
- 과거에 goal = psum[i] - K 인 값이 나온 적이 있다면, 그만큼 answer 를 증가시킨다.
- 즉, psum[j] = goal 인 j의 개수만큼 정답에 추가된다.
- count[psum[i]] 업데이트
- 현재 psum[i] 값을 count 에 추가하여, 이후에 같은 값이 나올 경우를 대비한다.
코드
# 백준 2015 - 수들의 합 4
# 분류 : 누적합
N, K = map(int, input().split())
A = list(map(int, input().split()))
psum = [0] * N
psum[0] = A[0]
for i in range(1, N) :
psum[i] = psum[i - 1] + A[i]
answer = 0
count = {}
for i in range(N) :
goal = psum[i] - K
if goal == 0:
answer += 1
if goal in count :
answer += count[goal]
if psum[i] not in count :
count[psum[i]] = 0
count[psum[i]] += 1
print(answer)