poj3061尺取法

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题意:找最小的连续的数来大于给定的数(好像这类题目都是要找连续的数额。。)题解:尺取法咯,当然还有别的方法只是时间复杂度高一点尺取法的:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 1000000007

using namespace std;

const int N=100000+5,maxn=100+5,inf=0x3f3f3f3f;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t,n,s,a[N],sum[N];
    cin>>t;
    while(t--){
        cin>>n>>s;
        for(int i=0;i<n;i++)cin>>a[i];
        int sum=0,st=0,en=0,ans=n+2;
        while(en<=n){
            while(sum<s&&en<=n){
                sum+=a[en++];
            }
        //    cout<<sum<<" "<<st<<" "<<en<<endl;
            if(sum>=s)ans=min(ans,en-st);
            sum-=a[st++];
        }
        if(ans==n+2)cout<<0<<endl;
        else cout<<ans<<endl;
    }
    return 0;

非尺取:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 1000000007

using namespace std;

const int N=100000+5,maxn=100+5,inf=0x3f3f3f3f;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t,n,s,a[N],sum[N];
    cin>>t;
    while(t--){
        cin>>n>>s;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
            if(i==0)sum[i]=a[i];
            else sum[i]=sum[i-1]+a[i];
        }
        int res=n+2;
        for(int i=0;sum[i]+s<=sum[n-1];i++)
        {
            int j=lower_bound(sum+i,sum+n,sum[i]+s)-sum;
      //      cout<<j<<endl;
            res=min(res,j-i);
        }
        if(sum[n-1]>=s)cout<<res<<endl;
        else cout<<0<<endl;
    }
    return 0;
}

时间: 2024-08-29 03:10:10

poj3061尺取法的相关文章

POJ3061 尺取法

题目大意:从给定序列里找出区间和大于等于S的最小区间的长度. 前阵子在zzuli OJ上见过类似的题,还好当时补题了.尺取法O(n) 的复杂度过掉的.尺取法:从头遍历,如果不满足条件,则将尺子尾 部增加,若满足条件,则逐渐减少尺子头部直到不满足条件为止,保存 尺子长度的最小值(尾部-头部+1)即可. 理论上累计区间和+二分查找的暴力也能过. 代码如下: #include <stdio.h> #include <algorithm> #include <string.h>

poj3061 Subsequence&amp;&amp;poj3320 Jessica&#39;s Reading Problem(尺取法)

这两道题都是用的尺取法.尺取法是<挑战程序设计竞赛>里讲的一种常用技巧. 就是O(n)的扫一遍数组,扫完了答案也就出来了,这过程中要求问题具有这样的性质:头指针向前走(s++)以后,尾指针(t)要么不动要么也往前走.满足这种特点的就可以考虑尺取法. poj3061 比较简单,也可以用二分做,时间复杂度O(n*logn).用尺取法可以O(n)解决. #include<iostream> #include<cstdio> #include<cstdlib> #i

尺取法 poj3061 poj3320

尺取法就是反复推进区间的开头和结尾,来求满足条件的最下区间. poj3061 http://poj.org/problem?id=3061 给定一个都是正整数的序列,要我们求总和不小于S的连续子序列的长度的最小值 如果序列   是总和最迟大于S的连续子序列 那么  所以只有加上, 从开始的连续子序列才有可能大于S 所以从开始的总和最初大于S的连续子序列是则一定有 1 #include <stdio.h> 2 #include <string.h> 3 #include <st

【尺取法】POJ3061 &amp; POJ3320

POJ3061-Subsequence [题目大意] 给定长度微n的数列整数及整数s.求出总和不小于s的连续子序列的长度的最小值.如果节不存在,则输出0. [思路] 尺取法五分钟裸裸裸~刷水刷出了罪恶感:( 基本做法:设置l和r代表当前区间[l,r],若S(l,r)<s,则 r++.若S(l,r)≥s,则 l++,直至S(l,r)<s.如果当前S(l,r)<s且r=n则退出.输出最小区间长度[l,r]即可. 1 #include<iostream> 2 #include<

POJ3061 Subsequence(二分前缀和法+尺取法)

二分+前缀和法 满足条件的子序列长度在(0,n)之间,sum[x+i]-sum[i]为从从第i个元素开始序列长度为x的元素的和.前缀和可在O(n)的时间内统计 sum[i]的值.再用二分找出满足条件的最小的子序列长度. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #

poj3061 Subsequence ,尺取法

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 sequen

poj3061(Subsequence)尺取法

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 o

poj3061(尺取法)

Subsequence 题意: 给出一个序列,要求找出一个长度最短的连续子区间,满足区间上所有数之和大于等于S,输出这个最短长度. 分析: 枚举每个点为左端点,用尺取法找到其右端点,取n次结果中的最小值就好了. 代码: #include <stack> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace st

【转】毛虫算法&mdash;&mdash;尺取法

转自http://www.myexception.cn/program/1839999.html 妹子满分~~~~ 毛毛虫算法--尺取法 有这么一类问题,需要在给的一组数据中找到不大于某一个上限的"最优连续子序列" 于是就有了这样一种方法,找这个子序列的过程很像毛毛虫爬行方式,我管它叫毛毛虫算法,比较流行的叫法是"尺取法". 喏,就像图里的妹纸一样~ 还是举个栗子: Poj3061 给长度为n的数组和一个整数m,求总和不小于m的连续子序列的最小长度 输入 n = 1