1. 程式人生 > 其它 >[MergeSort]1 奧運排行榜 (25分) HBU-DS 實驗

[MergeSort]1 奧運排行榜 (25分) HBU-DS 實驗

1 奧運排行榜 (25分)

每年奧運會各大媒體都會公佈一個排行榜,但是細心的讀者發現,不同國家的排行榜略有不同。比如中國金牌總數列第一的時候,中國媒體就公佈“金牌榜”;而美國的獎牌總數第一,於是美國媒體就公佈“獎牌榜”。如果人口少的國家公佈一個“國民人均獎牌榜”,說不定非洲的國家會成為榜魁…… 現在就請你寫一個程式,對每個前來諮詢的國家按照對其最有利的方式計算它的排名。

輸入格式:

輸入的第一行給出兩個正整數NM(≤224,因為世界上共有224個國家和地區),分別是參與排名的國家和地區的總個數、以及前來諮詢的國家的個數。為簡單起見,我們把國家從0 ~ N−1編號。之後有N行輸入,第i行給出編號為i

−1的國家的金牌數、獎牌數、國民人口數(單位為百萬),數字均為[0,1000]區間內的整數,用空格分隔。最後面一行給出M個前來諮詢的國家的編號,用空格分隔。

輸出格式:

在一行裡順序輸出前來諮詢的國家的排名:計算方式編號。其排名按照對該國家最有利的方式計算;計算方式編號為:金牌榜=1,獎牌榜=2,國民人均金牌榜=3,國民人均獎牌榜=4。輸出間以空格分隔,輸出結尾不能有多餘空格。

若某國在不同排名方式下有相同名次,則輸出編號最小的計算方式。

輸入樣例:

4 4
51 100 1000
36 110 300
6 14 32
5 18 40
0 1 2 3

輸出樣例:

1:1 1:2 1:3 1:4

~

非常坎坷的一道題。

先是想著怎麼寫一個函式,就能給結構體裡的不同屬性排序。

然後上午實驗課寫了半天的歸併。。。

剛才又寫了半天,發現排序那裡應該是誰多,誰在前面!而我寫反了!

關於臨界情況,等號的有無,心裡不是很清楚,感覺很亂。剛開始的cmp裡面,每個都有id的判斷(保證穩定性),但是這就導致我後面getRank出現了問題,導致測試點三四過不去。後來不管那個了,就過去了。仔細一想,這道題不用考慮穩定性,這是因為如果成績一樣我們認為排名是一樣的,而不是再根據id再排。 如果cmp裡沒有等號的話,對於這個題的排序來說,是沒有問題的,因為不用考慮穩定性,但是對於後面的getRank來說,就會出現問題,也是三四點過不去。

半個下午就這樣過去了。

程式碼

#include <iostream>
#include <vector>
using namespace std;
typedef struct Node Cou;
struct Node
{
    int id;
    int gold, medal, peonum;
    int rank[4];
};
bool cmp1(const Cou &c1, const Cou &c2)
{
    return c1.gold >= c2.gold;
}
bool cmp2(const Cou &c1, const Cou &c2)
{
    return c1.medal >= c2.medal;
}
bool cmp3(const Cou &c1, const Cou &c2)
{
    return ((double)c1.gold) / c1.peonum >= ((double)c2.gold) / c2.peonum;
}
bool cmp4(const Cou &c1, const Cou &c2)
{
    return ((double)c1.medal) / c1.peonum >= ((double)c2.medal) / c2.peonum;
}
bool cmp5(const Cou &c1, const Cou &c2)
{
    return c1.id < c2.id;
}
template <typename T>
void Merge(vector<T> &arr, int a, int b, int c, bool (*cmp)(const T &n1, const T &n2));

template <typename T>
void MergeSortRecursive(vector<T> &arr, int start, int end, bool (*cmp)(const T &n1, const T &n2));

template <typename T>
void Sort(vector<T> &arr, bool (*cmp)(const T &n1, const T &n2));

void GetRank(vector<Node> &arr, int k, bool (*cmp)(const Cou &c1, const Cou &c2))
{
    int rank = 1;
    arr[0].rank[k] = rank;
    for (int i = 1, len = arr.size(); i < len; ++i)
    {
        if (cmp(arr[i], arr[i - 1])) //因為 arr[i]>=arr[i-1] 現在要是 arr[i]<=arr[i-1] 說明 一樣大
            arr[i].rank[k] = rank;
        else
        {
            rank = i + 1;
            arr[i].rank[k] = rank;
        }
    }
}
void Print(const vector<Node> &coutry, int M)
{
    for (int c = 0; c < M; ++c)
    {
        int cur;
        cin >> cur;
        auto &x = coutry[cur];
        int min = 300;
        int way = 1;
        for (int i = 0; i < 4; ++i)
        {
            if (x.rank[i] < min)
            {
                min = x.rank[i];
                way = i + 1;
            }
        }
        if (c)
            printf(" ");
        printf("%d:%d", min, way);
    }
}
int main()
{
    int N, M;
    cin >> N >> M;
    vector<Node> coutry(N);
    for (int i = 0; i < N; ++i)
    {
        cin >> coutry[i].gold >> coutry[i].medal >> coutry[i].peonum;
        coutry[i].id = i;
    }

    Sort(coutry, cmp1);
    GetRank(coutry, 0, cmp1);
    Sort(coutry, cmp2);
    GetRank(coutry, 1, cmp2);
    Sort(coutry, cmp3);
    GetRank(coutry, 2, cmp3);
    Sort(coutry, cmp4);
    GetRank(coutry, 3, cmp4);
    Sort(coutry, cmp5);

    Print(coutry, M);
}

template <typename T>
void Merge(vector<T> &arr, int a, int b, int c, bool (*cmp)(const T &n1, const T &n2))
{
    vector<T> tmp(c - a + 1);
    int i1 = a, i2 = b + 1, i3 = 0;
    while (i1 <= b && i2 <= c)
    {
        if (cmp(arr[i1], arr[i2]))
            tmp[i3++] = arr[i1++];
        else
            tmp[i3++] = arr[i2++];
    }
    while (i1 <= b)
        tmp[i3++] = arr[i1++];
    while (i2 <= c)
        tmp[i3++] = arr[i2++];

    for (int i = 0; i < i3; ++i)
        arr[i + a] = tmp[i];
}

template <typename T>
void MergeSortRecursive(vector<T> &arr, int start, int end, bool (*cmp)(const T &n1, const T &n2))
{
    if (start < end)
    {
        int center = (start + end) / 2;
        MergeSortRecursive(arr, start, center, cmp);
        MergeSortRecursive(arr, center + 1, end, cmp);
        Merge(arr, start, center, end, cmp);
    }
}

template <typename T>
void Sort(vector<T> &arr, bool (*cmp)(const T &n1, const T &n2))
{
    MergeSortRecursive<T>(arr, 0, arr.size() - 1, cmp);
}