POJ 3061 Subsequence (尺取)
Description
给出一个长度为\(n\)的序列,求区间和大于等于\(s\)的连续区间的最小长度。
Input
第一行给出用例组数\(T\),对于每组用例,第一行给出\(n\)和\(k\),第二行给出\(n\)个整数表示这个序列。\(n \leqslant 10^5\)。
Output
对于每组用例,输出一个整数,表示满足条件的序列的最小长度。
Sample Input
2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5
Sample Output
2
3
Solution
尺取法模板题,限制条件是下限,区间和大于等于\(s\)。左端点依次推进,对于每个左端点,右端点向右直到找到第一个满足条件的位置,更新答案。如果右端点找到最右端也找不到合法区间了,就跳出。
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int a[N];
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
int n, s;
scanf("%d%d", &n, &s);
for (int i = 1; i <= n; i++) scanf("%d", a + i);
int ans = INF;
int r = 1, sum = 0;
for (int l = 1; l <= n; l++)
{
while (r <= n && sum < k) sum += a[r++];
if (sum < s) break;
ans = min(ans, r - l);
sum -= a[l];
}
printf("%d\n", ans < INF ? ans : 0);
}
return 0;
}