PTA 寻找大富翁 (归并排序)

1. 问题背景

胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人。假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁。

2. 输入格式:

输入首先给出两个正整数N(≤10​^6​​ )和M(≤10),其中N为总人数,M为需要找出的大富翁数;接下来一行给出N个人的个人资产值,以百万元为单位,为不超过长整型范围的整数。数字间以空格分隔。

3. 输出格式:

在一行内按非递增顺序输出资产排前M位的大富翁的个人资产值。数字间以空格分隔,但结尾不得有多余空格。

4. 输入输出样例:

//Input
8 3
8 12 7 3 20 9 5 18
//Output
20 18 12

5. 解题

  1. 要考虑M>N的情况
  2. 排序方法的选择,选择效率高的,要考虑最坏的情况,题目测试的一个点就是数据量大。比如快速排序会超时(自己写就会,使用系统的sort就不会),所以选择归并排序。
  3. 看到一个不错的方法解这个题:https://blog.csdn.net/qq_41799219/article/details/80555122
#include
#include

int k[1000005]; //原数组
int t[1000005]; //辅助数组

void Merge(int sr[],int tr[],int left,int mid,int right){
	//传递的都是下标,相当于在原数组和辅助数组空间中,用下标划分左右部分的子数组
    int i = left, ii = mid;
    int j = mid + 1, jj = right;
    int flag = left;
    while(i <= ii && j <= jj){//左右两部分数组比较着添加进tr,即辅助数组
        if(sr[i] > sr[j])//从大到小排序
            tr[flag++] = sr[i++];
        else
            tr[flag++] = sr[j++];
    }
    while(i <= ii)//将左半部分数组的剩余元素添加进tr
        tr[flag++] = sr[i++];
    while(j <= jj)//将右半部分数组的剩余元素添加进tr
        tr[flag++] = sr[j++];
    for(int index = left; index < flag; index++)//用辅助数组更新原数组
        sr[index] = tr[index];
}

void Msort(int sr[],int tr[],int left,int right){
    if(left < right)
    {
        int mid = (left + right) / 2;
        Msort(sr, tr, left, mid);//左半部分数组
        Msort(sr, tr, mid + 1, right);//右半部分数组
        Merge(sr, tr, left, mid, right);//合并
    }

}

int main(){
    int i,j;
    int n,m;

    scanf("%d %d",&n,&m);
    for(i=1;i<=n;i++)
        scanf("%d",&k[i]);
    Msort(k,t,1,n);
    if(n<m) // 考虑m>n的情况
        m=n;
    for(i=1;i<=m;i++)
        if(i==1)
            printf("%d",k[i]);
        else
            printf(" %d",k[i]);
}

你可能感兴趣的:(PTA程序设计)