【題解】Luogu P2397 yyy loves Maths VI (mode)
阿新 • • 發佈:2019-01-09
很有意思的一道題
Solution
初看此題毫無頭緒,2.2mb太喪心病狂了
再看題目,注意到重要性質:眾數個數大於一半
看完題解之後想到使用一個方法:摩爾投票法
摩爾投票法是啥玩意?
考慮一段序列,其中眾數的個數超過一半
每一輪投票,從序列中選出兩個不同的數,丟棄
無法再進行投票後,最終一定剩下大於等於一個全部相同的數,即眾數
會不會有剩兩種或以上不同的數?
不會。根據定義,此時我們還可以再進行一次投票
很好,可是要怎麼用到題目上面?
十分極限的空間限制要求我們的演算法空間複雜度為\(O(1)\)
以下引用自PauGasol的高票題解
我們來yy一個小房子,每當有數進來的時候,如果房子是空的,那麼將這個房子貼上自己的標籤。
如果房子裡已經有和自己相同數字了,那麼進去和它一起♂住。
如果房子裡有和自己不同的數字,帶一個走出♂房♂子。
最後房子裡還剩下的數一定就是眾數了。
生動形象,驚世駭俗,一針見血(bushi
實際上這就是在運用摩爾投票法了,每次走出去的兩個數字是不同的,最終剩下的數即是眾數
Code
#include <cstdio> using namespace std; int n; int cur,cnt; int main() { scanf("%d",&n); int t; for(register int i=1;i<=n;++i) { scanf("%d",&t); if(!cnt) cur=t; if(cur==t) ++cnt; else --cnt; } printf("%d",cur); }
Solution II
在我把這道題直球安利給機房P神@srydsf123之後,P神花了三秒鐘稍作思考,說我還是\(naive\),提出了一個跟位有點關係的解決方案
陣列\(cnt[i][j]\)表示第\(i\)位上為\(j\)的數字的個數
可以發現眾數各位上的各個數在所在位上的個數一定大於\(n/2\),且在所有數中個數最多
為什麼最多?
顯然其他的數字的個數一定小於\(n/2\)
Code
懶得打了