# [競程] 澳洲選舉 ###### tags: `競程` ## 問題 * ZeroJudge: [e592](https://zerojudge.tw/ShowProblem?problemid=e592) 澳洲的選票要求選民按照選擇的順序對候選人進行排名。 * 最初僅計算選民的第一順位。如果一個候選人獲得超過50%的選票,則該候選人當選。如果沒有候選人獲得超過50%的選票,則所有票數最少的候選人將被淘汰。 * 如果在某張選票上的第一順位候選人被淘汰了,則將後面順位往前移動。 重複進行上述步驟直到一名候選人獲得超過50%的選票或所有候選人並列為止。所有候選人並列則不回傳任何名字。 給定候選人數量`n`、候選人名單 `candidates`和全部選票內容`ballots`,設計一個函式回傳最後當選者的名字。 ## 範例 ```python 輸入:n = 3 candidates = ["Alice", "Bob", "Eve"] ballots = [[1, 2, 3], [2, 1, 3], [2, 3, 1], [1, 2, 3], [3, 1, 2]] 輸出:"Alice" ``` ## 思路 * 因為有50%門檻的限制條件,所以得到最高票候選人不能直接回傳,必須使用一個`while`迴圈,只有滿足特定條件才跳出這個迴圈並回傳答案。 * 人名、選票總數、選票序號之間的關聯需謹慎對待。 ## 解答 ```python= from numpy import argmax, argmin def vote(n, candidates, ballots): threshold = int(len(ballots) / 2) # 超過這個票數就是過半 while 1: if not candidates: return None stats = [0 for _ in range(n)] for b in ballots: for i in range(n): if b[i] == min(b): stats[i] += 1 if max(stats) > threshold: return candidates[argmax(stats)] else: minballot = min(stats) while candidates and min(stats) == minballot: loser = argmin(stats) stats.pop(loser) candidates.pop(loser) for b in ballots: b.pop(loser) n -= 1 ```