1. 程式人生 > 實用技巧 >活動投票

活動投票

活動投票( 思維題\(\star \))

  • 時限:\(0.5s\) 記憶體:\(2M\)

Descrption

  • 衡中活動很多,人也很多,一次活動有 \(n\) 個學生參與投票,現已知一名參賽選手票數超過半數,求其參賽號\(a_i\)(參賽號隨機,\(0\le a_i \le 2147483647\)) 。

Input

  • 第一行一個整數 \(n\)
  • 第二行 \(n\) 個整數 \(N_i\) 代表第 \(i\) 個學生所投選手的參賽號。

Output

  • 超過半數選手的參賽號。

Sample Input

10
5 1 2 5 5 2 3 5 5 5

Sample Output

5

Hint

  • \(100\%\) 的資料滿足:\(n ≤3000000\)
  • 來源:\(20180718\)

分析

  • 我們要求的數 \(x\) 的出現次數一定是比其他任何數的出現次數多,那麼我們把所有的不同的數之間相互配對,剩下的數就一定是我們要求的
    • \(3, 1, 4 ,5, 1, 1, 1, 5, 1, 1, 1, 1->(1,3)(1,4)(1,5)(1,5),1,1,1,1\)
  • 具體實現時採用按序消除的方法
    • 每次碰到一個數,如果它和上一個數不同,就把它和上一個數配對並消掉
    • 如果它和上一個數相同,就個數加一
    • 最後剩下的數就是答案。
  • 空間複雜度為:\(O(1)\),時間複雜度為 \(O(n)\)

Code

#include <bits/stdc++.h>
const int maxn=100+5,Inf=0x3f3f3f3f;

void Solve(){
    int cnt=0,ans,n;
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        int x;scanf("%d",&x);
        if(cnt==0)//全抵消了那暫定為答案
            ans=x,cnt++;
        else
            if(x!=ans) --cnt;//不相同就抵消一對
            else ++cnt;//相同的個數加一
    }
    printf("%d\n",ans);
}
int main() {
    Solve();
    return 0;
}