poj3061
说明
给出了N个正整数(10<N<100000)的序列,每个正整数小于或等于10000,以及一个正整数S(S<100000 000)。编写一个程序,找出序列中连续元素的子序列的最小长度,其和大于或等于S。
输入
第一行是测试用例的数量。对于每个测试用例,程序必须从第一行读取数字N和S,用间隔隔开。序列号在测试用例的第二行给出,用间隔隔开。输入将在文件结束时结束。
输出
对于每种情况,程序必须在输出文件的单独行上打印结果。如果没有答案,则打印0。
样本输入
2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5
样本输出
2
3
解题思路
要得出最短的连续数字和大于等于S,可以先找出满足此条件的连续段,再从中找出最短的。
保存起点终点两个数组下标,先不断挪动终点下标,求和,直到满足条件停止,存下此时连续元素的长度,再移动起点下标,减去前面的数字,更新最短长度,不满足则继续移动终点下标,循环直到数组结束,输出最小长度
此方法为尺取法
代码如下
#include <iostream>
using namespace std;
int b[100100];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,i;
long long s;
cin>>n>>s;
for(i=0;i<n;i++)
cin>>b[i];
int l=0,r=0;
long long sum=0;
int ans=0x3f3f3f3f;
while(r<n)
{
sum+=b[r];
while(sum>=s)
{
ans=min(ans,r-l+1);
l++;
sum-=b[l-1];
}
r++;
}
if(ans>n) ans = 0;
cout<<ans<<endl;
}
return 0;
}