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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章