「LG2397」yyy loves Maths VI (mode)

题目描述


他让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\n",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\n",in);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/cjgjh/p/9348537.html