문제 링크: https://www.acmicpc.net/problem/1806
투포인터로 푸는 문제입니다.
i=0, j=0부터 시작해서 [i, j] 구간의 합이 s 이상이면 j-i+1로 최소 길이를 업데이트하고, i를 1 늘립니다. 구간 합이 s 미만이면 j를 1 늘립니다.
구간의 합을 구할 때 반복문을 쓰면 시간초과가 나오겠죠? 그래서 첫 칸부터 i, j 이동에 따라 누적해줘야 합니다.
구간의 합이 s 이상이어서 i를 1 늘릴 때 i를 1 늘리기 전에 구간합에서 v[i]를 빼주고, 구간 합이 s 미만일 때 j를 1 늘린 뒤 v[j]를 구간합에 더해줍니다. 이때 j가 n이 되면 배열 범위를 벗어나는 것이니 예외처리를 해줘야 하고요
i, j를 늘리는 것과 v[i], v[j]를 구간 합에 빼거나 더하는 순서가 뒤바뀌면 안되겠죠?
설명을 좀 두리뭉실 하게 했는데;; 직접 그려보시면 바로 이해가 될겁니다
#include <bits/stdc++.h>
using namespace std;
const int INF = 987654321;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int n, s;
cin >> n >> s;
vector<int> v(n);
for (auto& c : v)
cin >> c;
int i = 0, j = 0;
int sum = v[0];
int min_len = INF;
while (1) {
if (sum >= s) {
min_len = min(min_len, j - i + 1);
sum -= v[i];
++i;
}
else {
++j;
if (j == n) break;
sum += v[j];
}
}
cout << (min_len==INF ? 0 : min_len) << '\n';
return 0;
}
반응형
'Online Judge > 백준' 카테고리의 다른 글
[백준][C++] 1764: 듣보잡 (0) | 2020.07.10 |
---|---|
[백준][C++] 2993: 세 부분 (0) | 2020.07.09 |
[백준][C++] 2473: 세 용액 (0) | 2020.07.08 |
[백준][C++] 2470: 두 용액 (0) | 2020.07.08 |
[백준][C++] 1987: 알파벳 (0) | 2020.07.08 |