본문 바로가기
PS 문제 풀이/Baekjoon

[BOJ] 백준 2003 수들의 합 2

by 까망 하르방 2021. 12. 23.
반응형

Approach

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

 

특정 구간에 있는 원소들 합 == M 인 구간이 몇개인지 구하는 문제이다.

N개의 원소에 나올 수 있는 모든 구간을

이중 for문으로 전수 조사해서 구할 수 있다.

void process() 
{
	for (int s = 0; s < N; ++s)
	{
		for (int e = s; e < N; ++e)
		{
			sum = 0;
			for (int i = s; i <= e; ++i)
			{
				sum += arr[i];
			}

			if (sum == M)
			{
				ans++;
			}
		}
	}
}

하지만 N^2 의 시간복잡도가 나오는데, "시간 초과" 결과가 나온다.


해당 문제는 투 포인터 기법을 이용해서 풀 수 있다.

처음 원소 시작점에서 [s, e]를 구간을 잡아서

해당 구간의 합 sum < M 이면 e를 증가시켜 구간 범위를 넓혀주고

구간의 합 sum >= M 이면 s를 증가시켜 구간 범위를 좁혀준다.

각 원소는 양수이므로, 구간 범위 합(sum)이 e가 증가할 때는 증가하지만

s가 증가할 때는 감소한다고 볼 수 있다.

 

변수 e가 끝지점인 N에 도달한다면 더 이상 구간을 늘릴 수 없기 때문에

탐색 종료 시점으로 둘 수 있다.

 

C++

#include <stdio.h>

const int MAX_N = 1e4 + 5;
int N, M, ans, sum, s, e;
int arr[MAX_N];

void process()
{
	while (true)
	{
		if (sum < M)
		{
			if (e == N) break;
			sum += arr[e++];
		}
		else  // sum >= M
		{
			sum -= arr[s++];
		}

		if (sum == M) ans++;
	}
}

int main() 
{
	// freopen("input.txt", "r", stdin);
	scanf("%d %d", &N, &M);
	for (int i = 0; i < N; i++)
	{
		scanf("%d", &arr[i]);
	}
		
	process();

	printf("%d\n", ans);
}

 

Java

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
	
		int N = Integer.parseInt(sc.next());
		int M = Integer.parseInt(sc.next());
		
		int[] arr = new int[N];
		
		for(int i=0; i<N; i++) {
			arr[i] = Integer.parseInt(sc.next());
		}
		
		int count = 0;
		int idx = 0;
		while(true) {
			int sum = 0;
			for(int i=idx; i<N; i++) {
				sum += arr[i];
				if(sum == M) {
					count++;
					break;
				}else if(sum > M) {
					break;
				}
			}
			idx++;
			if(idx >= N) {
				System.out.println(count);
				break;
			}
		}
	}
}
반응형

'PS 문제 풀이 > Baekjoon' 카테고리의 다른 글

[BOJ] 백준 2164 카드2  (0) 2021.12.27
[BOJ] 백준 2163 초콜릿 자르기  (0) 2021.12.24
[BOJ] 백준 2010 플러그  (0) 2021.12.23
[BOJ] 백준 15963 CASIO  (0) 2021.12.22
[BOJ] 백준 1991 트리순회  (0) 2021.12.14

댓글