今天做題遇到了一個這樣的題:
鏈接:https://ac.nowcoder.com/acm/problem/207028
來源:牛客網
第k小數
時間限制:C/C++ 3秒,其他語言6秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld
題目描述
給你一個長度爲n的序列,求序列中第k小數的多少。
輸入描述:
多組輸入,第一行讀入一個整數T表示有T組數據。
每組數據佔兩行,第一行爲兩個整數n,k,表示數列長度和k。
第二行爲n個用空格隔開的整數。
輸出描述:
對於每組數據,輸出它的第k小數是多少。
每組數據之間用空格隔開
示例1
輸入
2
5 2
1 4 2 3 4
3 3
3 2 1
輸出
2
3
備註:
t ≤ 10, 1 ≤ n ≤ 5×10^6, k ≤ n,數列裏每個數都在int範圍內
由於輸入比較多,請使用快讀讀取。
例如:
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
自己太垃圾了,想了一會兒不知道該怎麼做,瞅了一眼題解,有位大佬就是用了nth_element()
函數來解決了。頓時覺得自己孤陋寡聞了。
nth_element()
-
頭文件:
#include<algorithm>
-
nth_element
是部分排序算法,它重排[first, last)
中元素,使得:nth
所指向的元素被更改爲假如[first, last)
已排序則該位置會出現的元素。- 這個新的
nth
元素前的所有元素小於或等於新的nth
元素後的所有元素。
-
參數
- first, last - 定義待排序範圍的隨機訪問迭代器
- nth - 定義排序劃分點的隨機訪問迭代器
- policy - 所用的執行策略。細節見執行策略。
- comp - 比較函數對象(即滿足比較 (Compare) 概念的對象),若第一參數小於(即先序於)第二參數則返回 true 。
比較函數的簽名應等價於如下:
bool cmp(const Type1 &a, const Type2 &b);
-
注意:他是沒有返回值的,並且不能保證n位置兩邊是有序的。
示例:
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int a[] = {5,6,8,7,4,3,2,0,1};
//0,1,2,3,4,5,6,7,8
nth_element(a,a+1,a+10);
cout << "[*]The third largest num:" << a[2] << endl;
cout << "[*]Array a:" << endl;
for(int i=0;i<10;i++)
cout << a[i] << ' ';
cout << endl;
return 0;
}
/*
[*]The third largest num:2
[*]Array a:
0 1 2 5 4 3 6 7 8 9
*/
回到題目:
思路:利用快讀輸入數據,再用nth_element()
函數找到第k小數就可。
代碼:
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 5e6+5;
int arr[maxn];
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
int main() {
int T;
T = read();
while(T--) {
int n,k;
n = read();
k = read();
for(int i=0;i<n;i++)
arr[i] = read();
nth_element(arr,arr+k-1,arr+n);
printf("%d\n",arr[k-1]);
}
return 0;
}