[BOJ] 2003 수들의 합 2(Python3)

1 분 소요

문제

N개의 수로 된 수열 A[1], A[2], …, A[N] 이 있다. 이 수열의 i번째 수부터 j번째 수까지의 합 A[i] + A[i+1] + … + A[j-1] + A[j]가 M이 되는 경우의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N(1 ≤ N ≤ 10,000), M(1 ≤ M ≤ 300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], …, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.

출력

첫째 줄에 경우의 수를 출력한다.

예제

1
2
3
4
5
6
예제 입력 1  
4 2
1 1 1 1

예제 출력 1  
3
1
2
3
4
5
예제 입력 2  
10 5
1 2 3 4 2 5 3 1 1 2

예제 출력 2  

문제 풀이

아무리 풀어도 자꾸 시간초과가 떠서 몹시 화가났다…

맨처음에는 for문으로 하나씩 좌표를 방문해가며 0부터 해당 좌표까지의 합의 모든 경우의수를 구해 m과 비교했는데, 이러면 중복되는 계산이 많아 시간초과가 계속 뜬다.

이 문제는 투포인터로 풀어야 시간초과를 피할 수 있는 문제이다. 투 포인터는 왼쪽과 오른쪽의 두개의 포인터가 이동하면서 문제를 풀어내는 방식의 알고리즘으로, 중복이 적어 빠르게 좌표계를 이동하며 값을 얻을 수 있다.

start와 end를 각각 0과 1로 선언해주고, 이 포인터를 기준으로 슬라이싱해가며 합을 구한다. 합이 m과 같다면 경우의수를 세는 변수인 answer를 +1해주고, m보다 합이 작은경우는 end를 +1, m보다 크다면 start를 +1 해가며 모든 경우의수를 계산해준다.

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
n, m = map(int, input().split())
lst = list(map(int, input().split()))

start = 0
end = 1
answer = 0

while end <= n and start <= end:
    hap = sum(lst[start:end])
    
    if hap == m:
        answer += 1
        end += 1
    elif hap < m:
        end += 1
    else:
        start+= 1
    

print(answer)        
    

1
2
3
4 2
1 1 1 1
2

카테고리:

업데이트:

댓글남기기