POJ 3061 Subsequence(尺取法)

题目链接: 传送门

Subsequence

Time Limit: 1000MS     Memory Limit: 65536K

题目描述

给定长度为n的数列整数以及整数S。求出总和不小于S的连续子序列的长度的最小值。如果解不存在,则输出0。

思路

O(nlogn)算法

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		int N,S,i;
		int ans[100005] = {0},sum[100005] = {0};
		scanf("%d%d",&N,&S);
		int res = N;
		for (i = 0;i < N;i++)
		{
			scanf("%d",&ans[i]);
			sum[i + 1] = sum[i] + ans[i];
		}
		if (sum[i] < S)
		{
			res = 0;
		}
		else
		{
			for (i = 0;sum[i] + S < sum[N];i++)
			{
				int tmp = lower_bound(sum + i,sum + N,sum[i] + S) - sum;
				res = min(res,tmp - i);
			}
		}
		printf("%d\n",res);
	}
	return 0;
} 

O(n)

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		int N,S;
		int ans[100005] = {0};
		
		scanf("%d%d",&N,&S);
		for (int i = 0;i < N;i++)
		{
			scanf("%d",&ans[i]);
		}
	
		int res = N + 1;
		int sum = 0,t = 0,s = 0;
		for (;;)
		{
			while (t < N && sum < S)
			{
				sum += ans[t++];
			}
			if (sum < S)
			{
				break;
			}
			res = min(res,t - s);
			sum -= ans[s++];
		}
		
		if (res > N)
		{
			res = 0;
		}
		printf("%d\n",res);
	}
	return 0;
} 
posted @ 2016-05-19 16:02  zxzhang  阅读(125)  评论(0)    收藏  举报