https://www.acmicpc.net/problem/1806
1806번: 부분합
첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.
www.acmicpc.net
또 다른 투 포인터 문제입니다.
정확히는 슬라이딩 윈도라고 할 수 있겠네요.
기본적인 투 포인터가 데이터의 양 쪽 끝에서 좁혀 들어오면서 탐색한다면, 슬라이딩 윈도는 한쪽 끝에서 시작해서 연속된 특정 범위를 찾습니다.
조금 더 상세히 설명해 볼까요?
N길이의 수열에서 연속된 부분을 구한다는 것은, 연속된 부분합의 시작점과 끝점을 정한다는 뜻입니다.
즉 N*N개의 경우가 존재한다는 뜻입니다.
슬라이딩 윈도우는 이 시작점과 끝점을 모든 경우에 대해 계산해보지 않고, 현재 부분에서 조건보다 작으면 연속된 부분을 늘리고 크면 연속된 부분을 줄이면서 진행합니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static StringTokenizer st;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int S = Integer.parseInt(st.nextToken());
int[] num = new int[N];
st = new StringTokenizer(br.readLine());
for (int n = 0; n < N; n++) {
num[n] = Integer.parseInt(st.nextToken());
}
int left = 0;
int right = 1;
int sum = num[0];
int answer = 100_001;
while (left < N) {
if (sum >= S) {
answer = Math.min(answer, right - left);
sum -= num[left];
left++;
} else {
if (right == N) {
break;
} else {
sum += num[right];
right++;
}
}
}
if(answer == 100_001) {
System.out.println(0);
}else {
System.out.println(answer);
}
}
}
728x90
'🔍 알고리즘 > 백준 Java' 카테고리의 다른 글
[Java] 백준 1202번. 보석도둑 (골드2) (0) | 2021.12.03 |
---|---|
[Java] 백준 20040번. 사이클게임 (골드4) (0) | 2021.12.03 |
[Java] 백준 2467번. 용액 (골드5) (0) | 2021.12.02 |
[Java] 백준 2166번. 다각형의 면적 (골드5) (0) | 2021.12.02 |
[Java] 백준 14939번. 불끄기 (플래티넘5) (0) | 2021.12.02 |