Kattis - Conformity (UVa 11286)
題目
https://open.kattis.com/problems/conformity
http://domen111.github.io/UVa-Easy-Viewer/?11286
在一間大學當中有 $n$ 個學生,每個學生都可以選擇 5 種課程,並且課程以介於 $100$ ~ $499$ 之間的數字表示
每個學生選擇的課程會形成一個課程組合
現在學校想要統計每種課程組合有多少學生選擇,並且表揚那些選擇最受歡迎課程組合的學生
輸出總共要表揚多少學生
$1 \leq n \leq 10000$
想法
首先我們要先界定一下相同的課程組合,只要選擇的課程內容相同就是同一個課程組合
但是選擇的先後順序不同會讓我們很困擾,所以首先將所有學生選擇的課程按照其編號由小到大排序好
接下來,對我們來說全部學生的課程組合就是一群無序的資料了,針對這群無序的資料可以觀察排序後有沒有甚麼好的性質可以使用
我們會發現到,當我們將這群資料由小到大排序後,相同的課程組合會被放在一起
那麼我們只需要去統計這幾群相同的序列(相同的課程組合)總共有多少組,然後記錄下最多組的人數總和即可
那麼,要怎麼排序這群無序的資料呢?
一種方法是很直觀的依序依照每個元素的大小來排序,自訂一個 compare function
另一種想法是這樣的,首先觀察到每個學生只能選擇 $5$ 種課程,並且課程編號都是 $3$ 位數
那麼,將這些數字組合起來會是一個 $15$ 位數的數字,範圍在 long long 內
這樣就可以將這一群資料變成一個序列了!
詳細來說,我們的步驟是這樣
- 輸入
- 將每一位學生選擇的課程由小到大排序
- 將每個學生的課程組合組成一個 $15$ 位數的數字
- 將課程組合由小到大排序
- 從第 $1$ 個課程組合開始遍歷
- 如果課程組合 $i$ 和課程組合 $i-1$ 相同
將計數器 $+1$ - 如果課程組合 $i$ 和課程組合 $i-1$ 不相同
- 如果計數器的數值大於當前紀錄的最大值
更新最大值,並且更新答案 - 如果計數器的數值等同當前紀錄的最大值
將答案加上計數器的數值
無論如何都要將計數器重整
- 如果計數器的數值大於當前紀錄的最大值
- 如果課程組合 $i$ 和課程組合 $i-1$ 相同
Code
1 | //By Koios1143 |
複雜度分析
輸入時間複雜度為 $O(n)$
排序所有學生課程的時間複雜度為 $O(5nlog5) \approx O(n)$
所有學生組合成 15 位數的時間複雜度為 $O(5n) \approx O(n)$
排序所有課程組合的時間複雜度為 $O(nlogn)$
遍歷所有課程組合的時間複雜度為 $O(nlogn)$
總時間複雜度為 $O(3n + 2nlogn) \approx O(n + nlogn)$