活动投票
活动投票( 思维题\(\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;
}
hzoi