题目: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
}
}