codeforces 977C Less or Equal

题目

You are given a sequence of integers of length n and integer number k. You should print any integer number x in the range of [1;109] (i.e. 1x109 ) such that exactly k elements of given sequence are less than or equal to x.

Note that the sequence can contain equal elements.

If there is no such x , print “-1” (without quotes).

Input
The first line of the input contains integer numbers n and k (1n2105, 0kn ). The second line of the input contains n integer numbers a1,a2,,an ( 1ai109 ) — the sequence itself.

Output
Print any integer number x from range [1;109] such that exactly k elements of given sequence is less or equal to x.

If there is no such x , print “-1” (without quotes).

Examples

Input
7 4
3 7 5 1 10 3 20
Output
6

Input
7 2
3 7 5 1 10 3 20
Output
-1

Note
In the first example 5 is also a valid answer because the elements with indices [1,3,4,6] is less than or equal to 5 and obviously less than or equal to 6.

In the second example you cannot choose any number that only 2 elements of the given sequence will be less than or equal to this number because 3 elements of the given sequence will be also less than or equal to this number.

分析

【题意】
n 个数,输出一个x,满足:

  • x[1,109]
  • 恰好有 k 个数小于等于x

【思路】
维护一个“比 x 小的数的集合”,不断加入更大的数并更新x,直到集合有 k 个数为止。一旦加入了一个数,那么和它相等的数也要一并加入,所以集合的增长是不连续的。
【注意】
需要特判k为0的情况,此时 x 必须比最小的数还要小并且x1,所以最小的数必须大于1

k n的情况,只需要选一个比最大的数还大的数就行了

代码

#include<stdio.h>
#include<algorithm>
using std::sort;
#define N_max 200005

int arr[N_max];
int main() {
    int n,k;
    scanf("%d %d", &n, &k);
    for (int i = 0; i < n;++i) 
        scanf("%d", &arr[i]);

    sort(arr, arr + n);
    //循环的边界
    arr[n] = 1000000001;
    //cur之前的数已经加入集合
    int cur = 0;
    //特判k==0
    if (k == 0) {
        if (arr[0] <= 1)  printf("-1");
        else printf("%d",arr[0]-1); return 0;
    }
    //加入第一个数以及所有与它相等的数
    while (arr[cur] == arr[cur + 1])
            cur ++;
    for ( ;;) {
        if (cur + 1 == k){printf("%d", arr[cur+1]-1);break;}
        if (cur + 1 > k) {printf("-1"); return 0;}
        //覆盖到下一个连续段的末尾
        cur++;
        while (arr[cur] == arr[cur + 1])
            cur ++;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值