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]);
}