Subsequence---poj3061(尺取法||二分)

题目链接:http://poj.org/problem?id=3061

题意:给n个正整数和一个数S,求出总和不小于S的连续子序列的长度的最小值,如果无解输出0;

我们可以用sum[i]表示前i项的和;然后二分枚举找答案即可时间复杂度为O(n*logn)的;

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<math.h>
using namespace std;
#define N 120000
#define PI 4*atan(1.0)
#define mod 110119
#define met(a, b) memset(a, b, sizeof(a))
typedef long long LL;

int a[N], n, s, sum[N];

int Judge(int len)
{
    for(int i=1; i+len-1<=n; i++)
    {
        if(sum[i+len-1]-sum[i-1]>=s)
            return 1;
    }
    return 0;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d", &n, &s);

        for(int i=1; i<=n; i++)
        {
            scanf("%d", &a[i]);
            sum[i] = sum[i-1] + a[i];
        }

        int L = 1, R = n, Min = 0;

        while(L <= R)
        {
            int Mid = (L+R)/2;
            if(Judge(Mid))
            {
                Min = Mid;
                R = Mid-1;
            }
            else
                L = Mid+1;
        }
        printf("%d\n", Min);
    }
    return 0;
}

还可以用尺取法,就是用两个指针控制一下头和尾,然后移动即可;时间复杂度是O(n)的;

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<math.h>
using namespace std;
#define N 120000
#define PI 4*atan(1.0)
#define mod 110119
#define met(a, b) memset(a, b, sizeof(a))
typedef long long LL;

int a[N], n, s;

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d", &n, &s);

        for(int i=1; i<=n; i++)
            scanf("%d", &a[i]);

        int L = 1, R = 1, ans = n+1, sum = 0;

        while(1)
        {
            while(R<=n && sum<s)
                sum += a[R++];
            if(sum < s) break;
            ans = min(ans, R-L);
            sum -= a[L++];
        }
        if(ans == n+1)ans = 0;
        printf("%d\n", ans);
    }
    return 0;
}

时间: 2024-10-05 08:31:56

Subsequence---poj3061(尺取法||二分)的相关文章

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

POJ 3061 Subsequence(尺取法)

传送门 Subsequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11284 Accepted: 4694 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) ar

POJ3061 尺取法

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

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 sequen

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&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

POJ 3061 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

POJ 3061 Subsequence ( 二分 || 尺取法 )

题意 : 找出给定序列长度最小的子序列,子序列的和要求满足大于或者等于 S,如果存在则输出最小长度.否则输出 0(序列的元素都是大于 0 小于10000) 分析 : 有关子序列和的问题,都可以考虑采用先构造前缀和的方式来进行接下来的操作 ( 任意子序列的和都能由某两个前缀和的差表示 ). 二分做法 ==> 我们枚举起点,对于每一个起点 St 二分查找看看 St 后面有没有前缀和是大于或者等于 [ St的前缀和 ] + S 的,如果有说明从当前起点开始有一个终点使得起终之和是大于或者等于 S 的,