尺取法裸题,给一串数列和一个S,求数列中的某个大于S的子数列长度最小。
介绍一下尺取法:
尺取法也叫 two pointer ,顾名思义,像尺子一样,一块一块的截取。尺取法比直接暴力枚举区间效率高很多,尤其是数据量大的时候,所以说尺取法是一种高效的枚举区间的方法,是一种技巧。用尺取法来优化,可以使复杂度降为O(n)。是不是解释的有点让人纳闷~。。没关系,下面我们通过这个题目来体会尺取法的魅力。
尺取法的整个过程分为4部:
1.初始化左右端点
2.不断扩大右端点,直到满足条件
3.如果第二步中无法满足条件,则终止,否则更新结果
4.将左端点扩大1,然后回到第二步

#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+7;
int a[N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n, s;
        scanf("%d %d",&n, &s);
        for(int i=1; i<=n; i++)
            scanf("%d", &a[i]);
        int mi=1e9;
        for(int l=1,r=0,sum=0; r<=n; ++l)
        {
            while(r<=n && sum<s) sum+=a[++r];
            if(sum>=s) mi=min(mi,r-l+1);
            sum-=a[l]; 
        }
        printf("%d\n",mi==1e9 ? 0 : mi);
    }
}