[BOJ] 2003 수들의 합 2(Python3)
문제
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
댓글남기기