알고리즘

백준 1806번 부분합 (JAVA)

박카스마시며코딩 2023. 7. 6. 14:39

https://www.acmicpc.net/problem/1806

 

1806번: 부분합

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

www.acmicpc.net

 

저는 투 포인트를 이용해 문제를 해결하였습니다.

투 포인트를 통해 해당 포인터 사이의 합을 구하고 이 값을 s와 비교하여 작다면 끝 포인트를 늘리고 작거나 같다면 시작 포인트를 늘리면서 합이 s 이상인 길이를 추적하여 최소의 값을 찾았습니다.

 

package BOJ.twopoint;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.function.Function;

public class BOJ_1806 {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        Function<String,Integer> stoi = Integer::parseInt;
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = stoi.apply(st.nextToken());
        int s = stoi.apply(st.nextToken());
        int[] number = new int[n];
        st = new StringTokenizer(br.readLine());
        for(int i = 0 ; i < n ; i++){
            number[i] = stoi.apply(st.nextToken());
        }
        int result = cal(number,n,s);
        System.out.println(result);
    }

    private static final int NOT_FOUND = 0;

    private static int cal(int[] number, int n, int s) {
        int sum = 0;
        int si = 0;
        int ei = 0;
        int result = NOT_FOUND;
        while(true){
            if(sum < s){
                if(ei >= n){
                    break;
                }
                sum += number[ei++];
            }else{
                if(result == NOT_FOUND){
                    result = ei - si;
                }else{
                    result = Math.min(result,ei-si);
                }
                sum -= number[si++];
            }
        }
        return result;
    }
}