尺取法:对数组保存一对下标(起点,终点),然后根据实际情况交替推进两个端点直到得出答案。用于解决连续区间问题。
题意:给定长度为n的数列整数及S,求出总和不小于S的连续子序列的长度的最小值,不存在则输出1.
input :n=10,S=15,a={5,1,3,5,10,7,4,9,2,8} otput:2(5+10)
步骤:1.初始化起点终点,s=t=sum=0.
2.只要依然有sum<S,就不断将sum增加a[t],并将t+1.
3.如果(2)中无法满足sum>=S,终止,否则更新res=min(res,sum).
4.将sum-a[s],s+1,然后回到(2).
如下图,以测试1为例。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
int T,n,S,i;
int a[100100];
scanf ("%d",&T);
while (T--){
scanf ("%d %d",&n,&S);
for (i=0;i<n;i++){
scanf ("%d",&a[i]);
}
int res=n+1;
int sum=0;
int s=0;
int t=0;
for (;;){//核心代码
while (sum<S&&t<n){
sum+=a[t++];//扩大右端点
}
if (sum<S) break;
res=min(res,t-s);
sum-=a[s++];//左端点往右移
}
if (res>n)
res=0;
printf ("%d\n",res);
}
return 0;
}