题目链接
题目大意
找出总和不小于k的连续子序列长度的最小值
题目思路
1:首先可以直接暴力复杂度为n^2,无价值意义
2:看到连续的求和,就可以想到前缀和,找出前缀和,然后二分,复杂度为nlog(n)
3:尺取法,顾名思义,像尺子一样取一段,尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况
不断地推进区间左右端点以得出答案。复杂度o(n)
尺取法步骤
(1)初始化左右端点为了L,R。
(2)不断扩大右端点R,直到满足条件:L,R之间的数之和大于等于S。
(3)若第2步无法满足要求,则终止,否则更新最小值。
(4)将左端点L+1,逐渐缩短区间长度,以求得最小值,回到第2步。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
int t,n,k,a[maxn],sum[maxn];
int main()
{
scanf("%d",&t);
while(t--)
{
int ans=inf;
memset(a,0,sizeof(a));
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int s=0,r=1,l=1;
while(1)
{
while(r<=n&&s<k)
{
s=s+a[r++];
}
if(s<k) break;
ans=min(ans,r-l);
s=s-a[l++];
}
if(ans!=inf)
{
printf("%d\n",ans);
}
else
{
printf("0\n");
}
}
}