zoukankan      html  css  js  c++  java
  • Odd-Even Subsequence

    题意:

    在长 (n) 的序列 (a) 中保留 (k) 个数,形成一个新的子序列为 (s)。统计 (s) 中所有奇数索引上的最大值和偶数索引上的最大值,取二者的最小值,为结果。求最小的结果。
    (2leq k leq n leq 2*10^5)
    传送门

    分析:

    最终的结果不是取奇下标的最大值,就是取偶下标的最大值。
    二分枚举最终的答案,分别验证奇下标和偶下标是否满足,二者有一个满足就行。即对于当前的数 (x) ,在原序列中找出 (frac{k+1}{2}) 个充当奇下标的数,每找到一个就把其下一个当作偶下标。如果能找到满足条件的个数,表示该值满足条件。对于偶下标类似。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+5;
    int a[N],n;
    bool check1(int x,int m)//奇数
    {
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]<=x)
            {
                cnt++;
                if(i<n) i++,cnt++;//注意计数,如果k为偶数,要满足后面还能找到一个数当偶下标
            }
            if(cnt>=m) return 1;
        }
        return 0;
    }
    bool check2(int x,int m)//偶数
    {
        int cnt=1;
        for(int i=2;i<=n;i++)//第一个数肯定是充当奇下标
        {
            if(a[i]<=x)
            {
                cnt++;
                if(i<n) i++,cnt++;
            }
            if(cnt>=m) return 1;
        }
        return 0;
    }
    int main()
    {
        int k;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int l=1,r=1e9+5;
        //cout<<(r<<1)<<endl;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(check1(mid,k)||check2(mid,k)) r=mid-1;
            else l=mid+1;
        }
        printf("%d
    ",l);
        return 0;
    }
    
    
  • 相关阅读:
    Java显示指定类型的文件
    Mysql B-Tree, B+Tree, B*树介绍
    java海量大文件数据处理方式
    RandomAccessFile读取文本简介
    ConcurrentHashMap1.7和1.8的不同实现
    Java并发中的CopyOnWrite容器
    Java阻塞队列的实现
    JVM之Java虚拟机详解
    Spring AOP的实现原理
    SpringMVC工作原理
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13190216.html
Copyright © 2011-2022 走看看