P1923求第k小的数

第一、topk问题(采用快排优化后的topk,时间复杂度为O(n)),然后cin输入一直超时,最后换成了scanf函数AC

#include "bits/stdc++.h"
using namespace std;
int a[5000005];
void topk(int start,int end,int k)
{
    int i = start;
    int j = end;
    int temp = a[start];
    while(i < j){
        while(i < j && a[j] >= temp)
            j--;
        while(i < j && a[i] <= temp)
            i++;
        if(i < j)
            swap(a[i],a[j]);
    }
    swap(a[i],a[start]);
    if(i == k)//如果找到了那个位置,则返回
        return;
    else if(i > k)//如果左边的数的长度已经大于k了,那么第k小的一定在左边
        topk(start,i - 1,k);
    else 
        topk(i + 1,end,k);//如果右边的数的长度已经大于k了,那么第k小的一定在右边
} 
int main()
{
 
int k,n; cin >> n >> k;
 
for(int i = 0;i < n;i++) scanf("%d",&a[i]);//注意这段代码,不能用cin,否则会超时
 topk(
0,n - 1,k);
 cout
<< a[k] << endl;//直接打印a[k]
 return 0;
}

 第二、利用c++ STL中的nth_element()函数解决,该函数的语法是nth_element(a,a + k,a + n),a为数组名,a+k是把第k小的数放在第a[k]这个位置,a+n是这个数组的结束地址,c++STL中的函数一般都是左闭右开区间。(这个函数的原型也是快速排序的分治,时间复杂度为O(n))

#include "bits/stdc++.h"
using namespace std;
int a[5000005];
int main()
{
    int n,k;
    cin >> n >> k;
    for(int i = 0;i < n;i++)
        scanf("%d",&a[i]);
    nth_element(a,a+k,a+n);//nth_element是stl中的一个库函数,该函数可以从某个序列中找到第 n 小的元素 K,
                            //并将 K 移动到序列中第 n 的位置处。 
                            //不仅如此,整个序列经过 nth_element () 函数处理后,
                            //所有位于 K 之前的元素都比 K 小,所有位于 K 之后的元素都比 K 大。
    cout << a[k] << endl;
    return 0;
}

 第三、采用快读优化后时间编程了0.2s,可见快读的重要性,代码如下:

#include "bits/stdc++.h"
using namespace std;
int a[5000005];
int read()//为什么要采用快读,因为字符输入会比整数输入快上很多 c++的cin和cout为了兼顾兼容性所以cin和cout时间很慢
{
    int x = 0;
    int code = 1;//表示符号的正负
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-')   code = -1;
        ch = getchar();//接收掉负号以及不要要的其他符号
    }
    while(ch >= '0' && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return code * x;
}
int main()
{
    int n,k;
    n = read();
    k = read();
    for(int i = 0;i < n;i++)
        a[i] = read();//如果此处为cin的话,则会超时,所以我们可以采用快读的方式写入数字,快读不适用于大量的空格,单个读入字符要比读入数字快得多
    nth_element(a,a+k,a+n);
    cout << a[k] << endl;
    return 0;
}

 

posted @ 2021-12-07 21:09  scannerkk  阅读(108)  评论(0)    收藏  举报