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
", Min);
    }
    return 0;
}
View Code

还可以用尺取法,就是用两个指针控制一下头和尾,然后移动即可;时间复杂度是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
", ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5786260.html