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;
}

http://poj.org/problem?id=3061

posted @ 2017-08-13 09:57  达达Mr_X  阅读(135)  评论(0)    收藏  举报