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