第k小的数
Time Limit: 3100 ms Memory Limit: 65536 KiB
Problem Description
现有一个包含n个整数(1<=n<=10000000)的无序序列(保证序列内元素各不相同),输入一个整数k(1<=k<=n),请用较快的方式找出该序列的第k小数并输出。
Input
多组输入。
首先输入一个数据组数T(1<=T<=100)
接下来是T组数据。
每组数据有两行。
第一行先输入两个整数,n和k。
接下来是一行输入n个由空格分开的互不相同的整数num(1<=num<=90000000)。
Output
对于每组数据,输出该组数据中第k小的数num。
Sample Input
1
6 4
3 2 5 1 4 6
Sample Output
4
呃,用快排超时,希尔排序就好了,想想为什么。
#include <stdio.h>
#include <stdlib.h>
#define N 90000100
int num[N];
/*void qusort( int *a, int lt, int rt )
{
if(lt >= rt) return;
int i = lt, j = rt, key = a[lt];
while(i<j)
{
while(i<j && a[j] >= key)
j--;
a[i] = a[j];
while(i<j && a[i] <= key)
i++;
a[j] = a[i];
}
a[i] = key;
qusort( a, lt, i-1 );
qusort( a, i+1, rt );
}*/
void shellsort(int a[],int n){
int i,j;
int dk = n/2;
while(dk>=1){
for(i=dk;i<n;i++){
int temp = a[i];
j = i - dk;
while(j>=0 && a[j]>temp){
a[j+dk] = a[j];
j = j - dk;
}
a[j+dk] = temp;
}
dk = dk/2;
}
}
int main()
{
int t;
while(~scanf("%d",&t))
{
while(t--)
{
int i, n, k;
scanf("%d %d", &n, &k);
for(i=0; i<n; i++)
{
scanf("%d", &num[i]);
}
//qusort(num, 0, n-1);
shellsort(num, n);
printf("%d\n", num[k-1]);
}
}
return 0;
}
—————————————————分割线————————————————————
\
图片源自网络,侵删
**
**
—————————————————分割线————————————————————
\
n天后,用快排AC了!!教师教学只学习了快排、冒泡、选择排序,为了放水放宽条件。
—————————————————分割线————————————————————\
正确算法:要求输出第k小的数,只需要用快排排好前k个就行,即讨论key与k的大小关系,只排需要的一部分;