尺取法(双指针)例题。暴力算法就是两重for循环枚举i和j的位置。这里我们可以进行优化:①当i到j的和≥s时,j就不需要往后移动了;②当i变成i+1时,由于i到j-1的和小于s,i到j的和≥s,因此i+1到j-1的和一定小于s。也就是说,当i加1时,j只需后移一位即可开始新一轮的判断。
这里从i到j的和,采用前缀和实现。注意,i到j的和是j的前缀和减去i-1的前缀和。
令a[0]=0,sum[0]=0,i从1开始循环,这样a[i-1]就不会越界。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100010];
ll sum[100010];//计算前缀和
int main(){
int T;
scanf("%d",&T);
while(T--){
ll n,s;
scanf("%lld %lld",&n,&s);
memset(a,0,sizeof(a));
memset(sum,0,sizeof(sum));
sum[0]=0;
for(ll i=1;i<=n;i++){
scanf("%lld",&a[i]);//a从下标1开始,下标0设为0,方便后续sum[j]-sum[i]
sum[i]=sum[i-1]+a[i];
}
ll j=0;
ll ans=100020;
for(ll i=1;i<=n;i++){
while(j<=n && sum[j]-sum[i-1]<s) j++;//注意从i加到j,是j的前缀和减去i-1的前缀和
if(j>n) break;
ans=min(ans,j-i+1);
j--;
}
if(ans==100020) printf("0\n");
else printf("%d\n",ans);
}
return 0;
}
京公网安备 11010502036488号