(Java) 백준 2003번 - 수들의 합 2

코딩너구리·2026년 2월 16일

코딩 문제 풀이

목록 보기
224/266

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

문제

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

접근

주어진 배열 A에 대해 누적합을 구해둔다.
맨 마지막 인덱스의 누적합을 right, 맨 마지막 -1 번째를 left로 두고 right에서 left를 빼나간다.
뺀 값이 M보다 작으면 left를 0번 인덱스에 가까워지도록 -1씩 해주고, M보다 크거나 같을 땐 right를 -1해준다.
이 때, M과 같다면 경우의 수를 누적해준다.

문제해결

> 수열의 원소 수 N과 원하는 누적합M을 입력받는다.
> num배열에 수열을 입력받고, sum배열에 누적합을 구해 저장한다.
> left를 sum배열의 size-2로 뒤에서 두번째 원소를 가리키고,
right를 size-1로 마지막 원소를 가리킨다.
> while문으로 left가 음수, 배열의 범위를 벗어날 때까지 반복하며 rst에 경우의 수를 누적한다.
> right, left인덱스에 있는 누적합의 차이가 M보다 작으면 left를 왼쪽으로 민다.
> 크거나 같으면 right를 왼쪽으로 미는데 같을 땐 경우의 수를 누적한다.

코드

import java.io.*;
import java.util.*;
import java.lang.*;

public class Main {
    //2003번 수들의 합2
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    public static void main(String[] args) throws IOException {
        st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        int[] sum = new int[N+1];
        int[] num = new int[N+1];
        sum[0] = num[0] = 0;
        st = new StringTokenizer(br.readLine());
        for(int i = 1; i <= N; i++) {
            num[i] = Integer.parseInt(st.nextToken());
            sum[i] = sum[i-1] + num[i];
        }
        int left = sum.length-2;
        int right = sum.length-1;
        int rst = 0;
        while(left >= 0) {
            int diff = sum[right] - sum[left];
            if(diff < M) {
                left--;
                continue;
            }
            if(diff == M) rst++;
            right--;
        }
        System.out.print(rst);
    }
}

후기

누적합을 구해서 두 포인터로 뒤에서부터 따져줬지만 누적합을 사용하지않고 두 포인터만으로 num배열의 첫 인덱스부터 시작해서 합이 M보다 작다면 right를 계속 증가시킨다.
그러다 M보다 커지거나 같아지면 left를 증가시키며
즉석에서 합을 계산해나가는 방법이 있었다.

0개의 댓글