您的位置:首页 > 产品设计 > UI/UE

Poj - 3061 - Subsequence 【最基础的尺取法裸题】

2017-10-11 21:28 337 查看

Subsequence

Time Limit: 1000MS Memory Limit: 65536K

Total Submissions: 16740 Accepted: 7111

Description

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequence, the sum of which is greater than or equal to S.

Input

The first line is the number of test cases. For each test case the program has to read the numbers N and S, separated by an interval, from the first line. The numbers of the sequence are given in the second line of the test case, separated by intervals. The input will finish with the end of file.

Output

For each the case the program has to print the result on separate line of the output file.if no answer, print 0.

Sample Input

2

10 15

5 1 3 5 10 7 4 9 2 8

5 11

1 2 3 4 5

Sample Output

2

3

Source

Southeastern Europe 2006

题意: 给你一个N,S,N表示数列的个数,S表示一个和,问你最小的一个连续的序列使之它们的和大于等于S,求最短的序列长度,其中 10<N<100000,S<100000000,,如果没有这个序列输出0。

分析:在没有考虑尺取之前呢,我们可以考虑维护一个前缀和,然后枚举左端点点,然后二分查找右端点,这样的负责度是nlgn的,也是很客观的,但是有一个更方便的做法就是,我们枚举两个端点,记做 l,r,一开始先让r向右移动,一直记录一个sum,直到sum大于等于S,更新下答案,然后再让左端点移动,也随之更新答案,直到出现sum小于S后,右端点再移动,重复即可,直到左右端点到头为止(当然也不用到头,到时break下就行了)oAo其实这就是尺取法的一个基本思想,不少题就是根据这个思想来进行拓展的,因为我也是新开始直到这块,慢慢学吧

参考代码

//这题爆int注意
#include <cstdio>
#include <iostream>
#include <algorithm>
#define ll long long

using namespace std;

const int N = 1e5 + 10;
int a
;

int main(){
ios_base::sync_with_stdio(0);
int T;cin>>T;
while(T--){
int n,s;
ll S = 0;
cin>>n>>s;
for (int i = 1;i <= n;i++) cin>>a[i],S += 1ll*a[i];
if(S < s){cout<<0<<endl;continue;}//特判下
int l,r,ans = INF;
ll t;
l = r = 1;
t = 1ll*a[1];
while(l <= n){
while(t < s && r < n) t += 1ll*a[++r];
ans = min (ans,r-l+1);
t -= 1ll*a[l++];
if(r == n && t < s)break;
}
cout<<ans<<endl;
}
return 0;
}


如有错误或遗漏,请私聊下UP,thx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: