zoukankan      html  css  js  c++  java
  • 子序列(尺取模板题)

    poj3061

    学习博客:

    语言:
    子序列
    时限: 1000MS   内存限制: 65536K
    提交总数: 33893   接受: 14062

    描述

    给出了一个N个正整数(10 <N <100 000)的序列,每个正整数小于或等于10000,并给出了一个正整数S(S <100 000 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了,那么不需要在向后推进右端点了,因为其和也肯定大于等于S但长度更长,所以,当区间和小于S时右端点向右移动,和大于等于S时,左端点向右移动以进一步找到最短的区间,如果右端点移动到区间末尾其和还不大于等于S,结束区间的枚举。

    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1e6+100;
    int a[maxn];
    int n,s;
    int ans; 
    void solve(){
        ans=0x3f3f3f;
        int l=1,r=1,sum=0,res=0;
        while(r<=n){
            while(sum<s&&r<=n){
                sum+=a[r];
                ++r;
                ++res;
            }        
            while(sum>=s){
                sum-=a[l];
                l++;
                --res;        
            }
            ans=min(ans,res+1); 
        }
        
    }
    int main(){
        int t;
        cin>>t;
        while(t--){
            cin>>n>>s;
            int sum=0;
            int flag=0; 
            for(int i=1;i<=n;i++){
                cin>>a[i];
                sum+=a[i];
            }
            if(sum<s){
                printf("0
    ");
            } 
            else{
                solve();
                printf("%d
    ",ans);
            }
        }
    } 
  • 相关阅读:
    整理Xen理论知识
    搭建Hadoop
    Java、中Date的格式初始化以及Calendar的使用
    学习Xen
    关于mpi的理论知识以及编写程序来实现数据积分中的梯形积分法。
    题解-CF1396C Monster Invaders
    题解-CF1139D Steps to One
    qq 表情库
    题解-洛谷P6788 「EZEC-3」四月樱花
    题解-CF1401E Divide Square
  • 原文地址:https://www.cnblogs.com/lipu123/p/13726836.html
Copyright © 2011-2022 走看看