题目描述;
给定长度为n的数列整数a0,….,an-1以及整数S。求出总和不小于S的连续子序列的长度的最小值。如果解不存在输出0.
解题思路:
先用前缀和处理一下数列,这样一来枚举起始元素s,然后用二分法确定不小于S的结尾t的最小值。时间复杂度O(nlogn)。
但是根据sum数列单调递增,那么可以有以下方法:
1. s=t=sum=0;
2. 只要依然有sum<S,就不断将sum增加at,将t++;
3. Sum>S后终止,更新res=min(res,t-s);
4. Sum减去as,s++,重复2;
时间复杂度O(n);
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int t,n,k;
long long sum[100010];
void solve(){
int min=n,l=0,r=1;
while (r<=n){
if (sum[r]-sum[l]<k) r++;
else{
if (r-l<min) min=r-l;
l++;
}
//cout<<l<<" "<<r<<endl;
}
if (sum[n]<k) cout<<"0"<<endl;
else cout<<min<<endl;
}
int main(){
cin>>t;
while (t--){
memset(sum,0,sizeof(sum));
cin>>n>>k;
for (int i=1;i<=n;i++){
int tmp;
scanf("%d",&tmp);
sum[i]=sum[i-1]+tmp;
}
solve();
}
}