题解 | #K-th Number#

K-th Number

https://ac.nowcoder.com/acm/problem/14301

首先可知答案的数字具有一定的单调性。考虑使用二分答案的方式。
如何验证:已知这个数字,去区间里面找有多少个数比当前这个数字大,如果数量大于等于m的话证明该数小了,需要向右移动反之向左移动。
在统计区间里面有多少个数比当前的数字大的时候,要注意使用双指针的方式,否则会超时。还有就是要用long long。
//双指针加二分做法。
#include <bits/stdc++.h>
typedef long long ll;

using namespace std;
const int maxn = 1e5+10;
ll N, K, M;
ll a[maxn];

bool yanz(ll x)
{
    ll num=0,s=0;
    for(int i=1,j=1;j<=N;j++)
    {
        if(a[j]>=x) num++;///值大于X
        if(num==K)///出现k个值大于等于X
        {
            s+=N-j+1;///将右边界大于等于j的区间都算上
            while(a[i]<x) s+=N-j+1,i++;///左边界右移 如果num没少 又加一次右边界等于大于j的区间
            num--;i++;///这个左边界值大于X
        }
    }
    return s>=M;
}


int main() {
    int T, max;
    scanf("%d", &T);
    while (T--) {
        scanf("%lld %lld %lld", &N, &K, &M);
        for (int i=1;i<=N;i++) {
            scanf("%lld", a+i);
            max = max>a[i]? max:a[i];
        }
        //二分答案
        ll l = 1, r = 1e9, ans=0;
        while (l<r) {
            ll mid = (l+r+1)/2;
            if (yanz(mid)) {
                ans = mid;
                l = mid;
            }
            else r = mid-1;
        }
        printf("%lld\n", ans);
//         cout<<yanz(8)<<endl;
    }
    
    
    return 0;
}


全部评论

相关推荐

点赞 评论 收藏
分享
07-09 18:28
门头沟学院 Java
写着提前批,结果还要实习4个月以上???
程序员牛肉:这种不用看,直接投了,面试的时候问对应的HR就行。有可能他们是直接复制的暑期实习的模板。
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-10 14:10
啊啊啊啊好幸福,妈妈是我找工作发疯前的一束光
黑皮白袜臭脚体育生:看了这篇帖子之后已经第一百次质问老妈,仍然没有得到我的老妈是老板的回答
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务