题目
求众数( n ≤ 2 ∗ 1 0 6 n≤2*10^6 n≤2∗106)
分析
首先数据点大到炸,排序是不可能的,所以有一种位运算的方法,把所有数统计二进制上是1的数位的个数,判断超过 1 2 n \frac{1}{2}n 21n的数位累加就是答案。
代码
#include <cstdio>
using namespace std;
int x,cnt[32],n,ans;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d",&x);
for (int j=0;(1<<j)<=x;j++)
if ((1<<j)&x) cnt[j]++;
}
for (int i=0;i<32;i++)
if (cnt[i]>n/2) ans+=1<<i;
printf("%d",ans);
}
再贴一个关于抵消法的代码
代码
#include <cstdio>
using namespace std;
int x,now,sum,n;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d",&x);
if (x==now) sum++;
else if (!sum) now=x;
else sum--;
}
printf("%d",now);
}