본문 바로가기
코딩테스트 준비/백준

[백준] 2003번 - 수들의 합 2 [Java]

by mwzz6 2025. 1. 17.

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

 

[백준] 2003번 - 수들의 합 2 [Java]


1.  아이디어

 

누적합과 브루트포스 알고리즘을 통한 방법과 투 포인터 알고리즘을 활용한 방법으로 해결할 수 있었다.


2. 문제풀이

 

- 누적합 + 브루트포스 알고리즘

주어진 문제가 수열에서 특정 구간의 합이 M이 되는 경우의 수를 구하는 문제이므로 누적합 배열을 미리 만든 후 2중 for문을 활용해 누적합 배열에서 두 원소의 차를 계산하는 방식으로 특정 구간의 합을 간단하게 구할 수 있다.

 

- 투 포인터 알고리즘

주어진 수열이 자연수로만 이루어진 수열이어서 두 개의 포인터를 앞쪽에서 출발시켜 두 포인터의 위치를 합을 구할 구간이라 생각하면 합을 줄이기 위해서는 왼쪽 포인터를, 합을 늘리기 위해서는 오른쪽 포인터를 오른쪽으로 이동시키는 것으로 볼 수 있다. 이를 활용해 포인터의 이동과 구간합 갱신을 같이 해주면 간단하게 구할 수 있다.


3. 코드

 

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        int[] arr = new int[N];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        int[] prefixSum = new int[1 + N];
        for (int i = 1; i <= N; i++) {
            prefixSum[i] = prefixSum[i - 1] + arr[i - 1];
        }

        int cnt = 0;
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j <= N; j++) {
                if (prefixSum[j] - prefixSum[i] == M) cnt++;
            }
        }

        System.out.println(cnt);
    }
}
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        int[] arr = new int[N];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        int left = 0;
        int right = 0;
        int sum = 0;
        int cnt = 0;

        while (true) {
            if (sum < M) {
                sum += arr[right++];
            } else if (sum > M) {
                sum -= arr[left++];
            } else {
                cnt++;
                sum -= arr[left++];
            }

            if (right == N && sum < M) break;
        }

        System.out.println(cnt);
    }
}

4. 후기

 

- 누적합 + 브루트포스 알고리즘

- 투 포인터 알고리즘