题目:https://www.acwing.com/problem/content/description/4939/

也许是一道双指针的入门题

思路:由于用双层嵌套循环,使用i,r作为子序列的左界和右界一路循环过去时间复杂度是o(n方),超出限制。使用双指针,让左界先等于1(起始点),右界一直往右移,直到已经移到尽头或符合要求了。如果符合要求,右界就没有必要往回移了(显著降低时间复杂度),因为数据全是整数,往回移右界更加不会达到题目要求,所以记录下此时的长度,并将左界(“指针”)右移,看看在接下来的区间有没有符合要求且长度更短的子序列。知道区间全部遍历完,如果len==n+1(因为序列长度总共为n,怎么样都取不到n+1)说明len没变,没找到sum>=goalsum故返回0,否则返回len(即最短长度)

代码:

#include<bits/stdc++.h>//#include<iostream>(cin与cout);#include<cstring>(memset)
using namespace std;
int a[100010];
int main()
{
    ios::sync_with_stdio(false);cin.tie(nullptr);
    int t;cin>>t;
    while (t -- )
    {
        int n,goalsum;cin>>n>>goalsum;
        memset(a, 0, sizeof(a));
        for (int i = 1; i <= n; i ++ ){cin>>a[i];}
        int len=n+1;
        for (int i = 1,sum=0,r=1;i <= n; i ++ )
        {
            while(sum<goalsum && r<=n){sum+=a[r++];}
            if(sum>=goalsum)
            {
                len=min(len,r-i);//因为最后多了一次r++,故这里为[(r-1)-i]+1=r-i
                sum-=a[i];//把最第一项踢出去,配合上循环中的i++实现左“指针”右移一次
            }
            else {break;}//提前跳出循环,节约时间
        }
        if(len==n+1)cout<<"0\n";//1.别忘了换行2.len变量不能在循环体中声明,不然在这里访问不到len变量
        else {cout<<len<<"\n";}//别忘了打else不然结果是0还会多输出一个n+1
    }
}