题目描述
输入 n(1≤n<5000000 且n 为奇数)个数字 a_i(1 <= a_i <=10^9),输出这些数字的第 k 小的数。最小的数是第0小。
请尽量不要使用 nth_element
来写本题,因为本题的重点在于练习分治算法。
输入格式
无
输出格式
无
【输入输出样例 】
输入:
5 1 4 3 2 1 5
输出:
2
第一版代码:(未AC)
#include <iostream>
using namespace std;
int k[1000000];
int main()
{
int n,m,i,j,temp;
scanf("%d %d",&n,&m);
for(i=0;i<n;++i)
{
scanf("%d",&k[i]);
}
for(i=0;i<n;++i)
{
for(j=i+1;j<n;++j)
{
if(k[i]>k[j])
{
temp=k[i];
k[i]=k[j];
k[j]=temp;
}
}
}
printf("%d",k[m]);
return 0;
}
测试结果:
第二版代码(已AC):
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int num=1e7+5;
int k[num],b[num];
long long int n;
void check(long long int x,long long int y)
{
if(x==y) return;
long long int mid=(x+y)/2,left=x,right=mid+1,a=x; //设置左右和中间端点
check(x,mid);
check(mid+1,y);
while((left<=mid)&&(right<=y))
{
if(k[left]<=k[right])
{
b[a++]=k[left++];
}
else
{
b[a++]=k[right++];
}
}
while(left<=mid)
{
b[a++]=k[left++];
}
while(right<=y)
{
b[a++]=k[right++];
}
for(int i=x;i<=y;++i)
{
k[i]=b[i];
}
}
int main()
{
long long int m,i;
scanf("%d %d",&n,&m);
for(i=0;i<n;++i)
{
scanf("%d",&k[i]);
}
n=n-1;
check(0,n);
printf("%d",k[m]);
return 0;
}
From CSDN(使用nth_element)
#include<bits/stdc++.h>
using namespace std;
int x[5000005],k;
int main()
{
int n;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
scanf("%d",&x[i]);
nth_element(x,x+k,x+n);//简短又高效
printf("%d",x[k]);
}