SDUT OJ 第k小的数

94 阅读1分钟

第k小的数

Time Limit: 3100 ms  Memory Limit: 65536 KiB

Submit  Statistic

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的大小关系,只排需要的一部分;