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)尺取法
  • 相关阅读:
    基于opencv的摄像头的标定
    图像的角点简介
    周转时间和平均带权时间等
    QT各个版本的下载的地址
    参考文献格式
    sublime中的emmet插件的使用技巧
    sublime快捷键
    CSS布局居中
    Markdown 语法说明(简体中文版)
    sql作业题
  • 原文地址:https://www.cnblogs.com/thmyl/p/7211938.html
Copyright © 2011-2022 走看看