알고리즘 연습/투 포인터

[🥇4 / 백준 1806 / 파이썬] 부분합

김세진 2021. 9. 15. 15:41
반응형

 

 

1806번: 부분합

첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.

www.acmicpc.net

 

문제

10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.

출력

첫째 줄에 구하고자 하는 최소의 길이를 출력한다. 만일 그러한 합을 만드는 것이 불가능하다면 0을 출력하면 된다.

 

예제 입력 

10 15
5 1 3 5 10 7 4 9 2 8

예제 출력 

2

 

풀이

 

부분 수열의 합이 특정 값을 넘을 때, 그 길이가 최소가 되는 것을 구하는 문제이다.

두 포인터의 값만을 더하는 것이 아닌, 부분 수열의 총 합을 연속해서 구해야 한다.

 

조건을 만족하는 부분 수열의 최소 길이를 구해야 하기 때문에 정렬을 사용할 수 없다.

하지만 상관없다. 정확한 두 값의 합의 비교가 아니라 부분 수열의 합을 비교하기 때문이다.

 

이 문제와 유사한 내용의 문제의 풀이는 이전 포스팅에 작성했으므로 아래 포스팅을 참고하길 바란다.

 

 

[백준 2003 / 파이썬] 수들의 합 2

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

my-coding-notes.tistory.com

 

import sys
input = sys.stdin.readline

n,s = map(int,input().split())
a = list(map(int,input().split()))

i,j,summ,r = 0,0,0,float('inf')
while(True):
    if summ >= s and r > j-i:
        r = j-i
    if summ >= s:
        summ -= a[i]
        i+=1
    elif j == n:
        break
    else:
        summ += a[j]
        j+=1
print(r if r!=float('inf') else 0)
반응형