1131 Midterm #1 [30%] qtt 論壇排名

 

有一個人氣很旺的論壇 qtt, 因為方便管理而且又希望維持使用者的匿名性, 每一個註冊的使用者都有一個唯一的代號 (1~200000000 的正整數), 因為有很好的匿名性, 所以使用者發表意見都非常踴躍, 到了年底管理者想要統計一下每個使用者的發言次數, 對前兩名提昇一下使用者的等級, 現在想請你寫一個程式, 幫忙找出前兩名以及他們的發言次數。

 

輸入測試資料:
8 10 20 20 15 20 15 5 100↵
9 55 33 44 33 22 33 55 11 33↵
每一列為一個測試案例, 一開始是一個正整數 n (2<=n<=10000), 代表這個案例中有哪些使用者發言, 接下來有 n 個 1~200000000 的正整數, 代表 n 次發言的使用者代號, 串流結束代表測試資料結束, 測資中每一個測試案例前兩名的次數一定都不一樣, 也一定大於第三名的次數。

 

輸出測試資料:
20 3 15 2↵
33 4 55 2↵
每一列是一個測試案例的輸出, 以第一列來說, 20 是發言數量最多的使用者代號, 3 是他發言的次數, 15 是發言數量第二多的使用者代號, 2 是他發言的次數。

 


注意

  1. 2 億個元素的陣列是最直接的想法,
    int count[200000000]={0};
    int x, n, i, max;
    scanf("%d", &n);
    for (i=0; i<n; i++)
    {
        scanf("%d", &x);
        count[x]++;
    }
    // 由 count 陣列中找出最大值還有第二大的數值
    // 列印出最大值/次大值出現的位置以及其數值
    但是這樣子最大的問題是 200000000 個 int 大概需要 800MB, 很多環境裡根本沒有辦法讓你的程式用那麼大的陣列, 就算可以, 保留了這麼多個元素以後卻只用到 n 個, n 最多是 10000, 這樣子實在很浪費記憶體。

  2. 可以定義一個 10000 個元素的陣列, 把所有 n 個使用者代號讀進來, 運用迴圈去篩選相同的代號並且計算重複發言的次數, 隨時保留下前兩名的代號以及次數, 最後列印出結果。

  3. 如果你已經會使用陣列的排序, 不論是 qsort、氣泡排序法、或是選擇排序法, 可以很快地替所有發言的使用者代號陣列排序, 然後用迴圈計算每個使用者重複的次數, 隨時保留下前兩名的代號以及次數, 最後列印出結果。