Subsequence (尺取法)

Subsequence

https://ac.nowcoder.com/acm/problem/107658

尺取法(双指针)例题。暴力算法就是两重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;
}
全部评论

相关推荐

06-08 22:25
门头沟学院 Java
从零开始的转码生活:这hr不会打开手机不分青红皂白给所有人群发这句话,过一会再给所有人再发一遍,这肯定会有重复的,不管,再过一会再发一遍
点赞 评论 收藏
分享
牛客刘北:如果暑期实习是27届的话,你要晚一年才会毕业,企业为什么会等你呢?要搞清时间逻辑呀!27届现在实习只能是在暑假实习,这是日常实习,不是暑期实习。所以多去投日常实习吧,暑期实习肯定不会要你的
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务