算法入门课2-总结

K -th Number
链接:https://ac.nowcoder.com/acm/problem/14301
题目大意
给定数组A,将数组A中第k大的数加入数组B中,输出数组b中的第m大的数
易错点
本题没有给m的数据范围,由于数组A的大小为n,可以组成的区间大小为(n - 1) * n / 2
代码如下:
n为1e5,故m超出了int的范围要用long long

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;

int n, k, a[N];
ll m;
/*
    如果一个区间中有k个数>=x 说明res >= x
    如果这样的区间的总个数>=m 说明res <= x 
*/
bool check(int x) { //
    ll tot = 0;  //区间第k大的数大于x的区间有多少个
    for(int l = 1, r = 0, sum = 0; l <= n; l++) {  //快慢指针,快指针一开始要小于满指针
        while(r + 1 <= n && sum < k) {
            sum += a[++r] >= x; 
        }
        if(sum == k) tot += n - r + 1;  //从r到 n 大于等于x的数都成立
        sum -= a[l] >= x; //
    }
    return tot >= m;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d%lld", &n, &k, &m);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        int l = 1, r = 1000000000;
                /*
                    由于a[i]的范围为1 - 1e9
                    故 l = 1, r = 1e9
                */
        while(l < r) {
            int mid = (1 + l + r) >> 1;
            if(check(mid)) l = mid;  
            else r = mid - 1;
        }
        printf("%d\n", l);
    }
    return 0;
}
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务