题目描述:
给定若干整数,请设计一个高效的算法,确定第k小的数。
输入格式:
测试数据有多组,处理到文件尾。每组测试数据的第1行输入2个整数n,k(1≤k≤n≤1000000)。第2行输入n个整数,每个数据的取值范围在0到1000000之间。
输出格式:
对于每组测试,输出第k小的数。
输入样例:
5 3
1 2 2 2 1
9 3
1 2 3 4 5 6 9 8 7
输出样例:
2
3
提示:
如果提交后超时,请注意需要设计的是高效的算法!如果你初学《数据结构》,暂时设计不出来,请学完相关知识再回头来做。 也可以使用STL之sort、nth_element函数求解。 另外,由于输入数据特别多,为减少输入数据的耗时,建议使用以下的输入外挂函数:
void scan_d(int &num)
{
char in;
in=getchar();
while(in<'0'||in>'9') in=getchar();
num=in-'0';
while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}
}
调用方法如下:
int n;
scan_d(n);
这个题目上的提示部分由于比较复杂,我并没有使用,这道题也是自己斟酌了比较长的时间,最后看的班级大佬写的才算是看明白,也算是做出来了,但是也还存在一些问题。最后再说。
题目分析:
这道题有两个难点,第一个是实现循环输入;第二个是确定第k小的数;实现循环输入:
while(cin>>n){主要实现代码}
,这里要注意主要是现代吗都要在while循环里面,只有这样才能实现这些代码。
while(scanf("%d",&n)!=EOF){主要实现代码}
确定第k小的数,首先定义一个数组用来存储的输入的数字,然后把这些数字进行排序,最后直接输出数组的第k个下标的数字。
实现代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,k;
int a[1000000];
while(cin>>n){
scanf("%d",&k);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
printf("%d\n",a[k-1]);
}
return 0;
}
显示结果:
这里一定要注意的是主要实现代码块一定要写在while循环里面,查看输出结果的截图我们可以知道程序是每执行一段代码就直接输出执行结果,然后再继续执行下一组数字。
第二种代码演示:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,k;
int a[1000000];
while(scanf("%d",&n)!=EOF)
{
scanf("%d",&k);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
printf("%d\n",a[k-1]);
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/ddc4fa17cbde462b980fda8bed4b58a5.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Lit5LqM54aK54yr56iL5bqP54y_,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
这里面有一些毛病的就是当运行结果的时候显示程序直接退出,但是在pta平台运行测试答案是完全正确的。
![在这里插入图片描述](https://img-blog.csdnimg.cn/64e66a18354d424684842a9f3dfeeaf3.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Lit5LqM54aK54yr56iL5bqP54y_,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)