zoukankan      html  css  js  c++  java
  • poj3061 Subsequence

    Subsequence

     POJ - 3061 
    题目大意:
    给定长度为n的整数数列,以及整数S。求出总和不小于S的连续子序列的长度的最小值。若解不存在,则输出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
    /*
        求出前缀和,然后枚举区间起点 
        区间起点固定下来了之后,终点位置二分查找 
        不要忘了输出0的情况 
    */
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define maxn 100010
    int t,n,a[maxn],sum[maxn],s;
    int main(){
        //freopen("Cola.txt","r",stdin);
        scanf("%d",&t);
        while(t--){
            memset(a,0,sizeof(a));
            memset(sum,0,sizeof(sum));
            scanf("%d%d",&n,&s);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                sum[i]=sum[i-1]+a[i];
            }
            if(sum[n]<s){printf("0
    ");continue;}
            int ans=n;
            for(int i=1;i<=n;i++){//枚举起点 
                int l=i,r=n;//二分中点 
                while(l<=r){
                    int mid=(l+r)>>1;
                    int now=sum[mid]-sum[i-1];
                    if(now>=s)r=mid-1,ans=min(ans,mid-i+1);
                    else l=mid+1;
                }
            }
            printf("%d
    ",ans);
        }
    }
    O(nlogn)前缀和+二分查找
    /*
        尺取法:
        1.初始化s,t,sum
        2.只要依然有sum<m,就不断将sum加a[t],并将t加1
        3.如果(2)中无法满足sum>=m则终止。否则更新ans
        4.将sum减去a[s],s加1然后回到2 
        像区间右移 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define maxn 100010
    int T,n,t,a[maxn],s,m,sum;
    int main(){
        scanf("%d",&T);
        while(T--){
            s=1;t=0;
            sum=0;
            bool flag=0;
            scanf("%d%d",&n,&m);
            int ans=n;
            for(int i=1;i<=n;i++)scanf("%d",&a[i]);
            while(1){
                while(t<n&&sum<m)
                    sum+=a[++t];
                if(sum<m)break;
                ans=min(ans,t-s+1);flag=1;
                sum-=a[s];s++;
            }
            if(flag==0){printf("0
    ");continue;}
            else printf("%d
    ",ans);
        }
        return 0;
    } 
    O(n)尺取法
  • 相关阅读:
    Add Two Numbers
    Reverse Linked List II
    Reverse Linked List
    Remove Duplicates from Sorted List
    Remove Duplicates from Sorted List II
    Partition List
    Intersection of Two Linked Lists
    4Sum
    3Sum
    2Sum
  • 原文地址:https://www.cnblogs.com/thmyl/p/7211938.html
Copyright © 2011-2022 走看看