题目描述:
输入n个数,输出第K小的数。
输入格式:
第一行:两个数n和k,用一个空格分隔
接下来n行,每行一个数Ai
输出格式:
一个数,即第k小的数
样例输入:
5 3 2 6 8 3 1
样例输出:
3
提示:
对于30%的数据:n<=10;
对于70%的数据:n<=1,000;
对于100%的数据:n<=10,000,000;0<=Ai<=10^9
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 * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
注意,调用sort不行,sort本身效率是O(nlogn),而此题要求的效率必须是O(n)。
时间限制: 1000ms
空间限制: 128MB
题目难,难于上青天~~
这道题得用类似二分的思想,就对第k项所在的部分排序,降低时间复杂度(不能直接调用sort就像题目里说的)
代码实现:
#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[10000005];
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 * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
void sort(int l,int r){
if(l==r)return;
int key=a[(l+r)/2];
int i=l,j=r;
while(i<=j){
while(a[i]<key)i++;
while(a[j]>key)j--;
if (i<=j){
swap(a[i],a[j]);
i++,j--;
}
}
if(k<=j)sort(l,j);
if(k>=i)sort(i,r);
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)a[i]=read();
sort(1,n);
cout<<a[k];
}