简单的尺取法的题:
【试题描述】
给定长度为n的正整数数列A(A1, A2, ... , An)以及正整数S,求出总和不小于S的连续子序列的长度的最小值。如果解不存在,则输出0。
【输入】
第一行两个整数N和S,第二行包括n个正整数表示数列A,两两之间用空格分隔。
【输出】
一个符合题目要求的整数。
【输入示例】
11
1 2 3 4 5
【输出示例】
3
【其他说明】
数据范围:10 < N < 10^5,0 < Ai < 10^4+1,S < 10^8.
思路:
定义一个sum用来记录和是否大于S;
定义一个cut和cutt,用cutt储存最小的长度,则cut记录一般的值
程序要分情况讨论:
1、sum<S
2、sum≥S
下面是代码:
#include<iostream>
#include<algorithm>
using namespace std;
int a[100000];
int main()
{
int n,s,sum=0,cnt=0,cntt=INT_MAX;//cntt先为最大值
int i,j;
cin>>n>>s;//输入
for(i=0;i<n;i++)//输入
cin>>a[i];
i=0;j=0;//先清零
sum=a[0];//为后面的j++少加的数,先加上
cnt=1;//至少为一
while(i<=j&&j<n)//尺取法的边界条件
{
if(sum<s)//第一种情况
{
j++;//先j++就可以避免最后cnt多加
sum+=a[j];//累计连续数串的和
cnt++;//统计个数
}
else//第二种情况
{
cntt=min(cnt,cntt);//判断大小
sum-=a[i];//扔掉前一个数
cnt--;//因为扔掉了前一个数,所以个数-1
i++;//前面删去的数的位置
}
}
if(cntt==INT_MAX) cout<<0;//如果cntt没变,输出0
else cout<<cntt;//否则,输出cntt
return 0;
}
总的来说:小了就往后加一个同时记录数据,如果大或等于了就减去开头的数同时记录数据;