题目简介:在给定序列中寻找一段总和不少于S连续子序列的长度最小值。
10<n<10^5 多组数据
这个题很容易想到朴素算法,利用前缀和,不断更新满足sum[i]-sum[j-1]>=S中(i-j+1的最小值),但是此朴素算法的时间复杂度是O(n^2),对于此数据范围会TLE,于是想到利用前缀和nlogn的算法,此题就已经足够;
我们可以在输入的时候进行前缀和的计算,时间复杂度为O(n),计算的时间复杂度为nlogn,此题便可以过掉。
思路:枚举连续子序列的开始节点s,运用二分寻找使序列总和不小于S的结尾t的最小值,不断更新。即为答案。
如下代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 100200
using namespace std;
int a[N],s[N],n,S;
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>S;
int ans=N;
memset(s,0,sizeof(s));
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
}
if(s[n]<S)
cout<<"0"<<endl;
else
{
for(int i=1;s[i]+S<=s[n];i++)
{
int t=lower_bound(s+i,s+n+1,s[i]+S)-s;
ans=min(ans,t-i);
}
cout<<ans<<endl;
}
}
//while(1);
return 0;
}