题目描述
他让redbag找众数
他还特意表示,这个众数出现次数超过了一半
一共n个数,而且保证有
n<=2000000
而且每个数<2^31-1
输入输出格式
输入格式:
第一行一个整数n
第二行n个整数
输出格式:
一行,这个众数
输入输出样例
5
2 3 3 3 3
3
题解
Solution1
第一个思路还是比较难♂好想,对于每一个数取二进制的每一位计数,然后如果有一位上的个数比n/2大,就加进答案。最后和就是ans。
#include<stdio.h>
#include<stdlib.h>
inline int gi(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int have[40];
int main(){
int n,m;
scanf("%d",&n);
for(register int i=1;i<=n;i++){
scanf("%d",&m);
for(register int j=0;(1<<j)<=m;j++){
if((1<<j)&m)have[j]++;
}
}
int ans=0;
for(register int i=0;i<=30;i++){
if(have[i]>n/2)ans+=1<<i;
}
printf("%d
",ans);
return 0;
}
Solution2
第二个思路用到的是摩尔投票法,这种方法一般适用于求众数时众数数量比一半多.
首先我们可以证明这样子的数必然只有一个,如果有两个总共就不只n个数了.然后再仔细想一想,就发现这道题目比较愚蠢良心,用一个变量记录当前里面的数,如果相同就累计,不同就减掉.这样重复下去,剩下的数必然是众数.
#include<stdio.h>
#include<stdlib.h>
inline int gi(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int main(){
int n,m;
scanf("%d",&n);int now=0,in;
for(register int i=1;i<=n;i++){
scanf("%d",&m);
if(!now || m==in){now++;in=m;}
else now--;
}
printf("%d
",in);
return 0;
}