题目描述
传智专修学员的课堂上,为了活跃气氛,并巩固位运算的知识,同学们玩起了一个游戏。
班级里有 n(n≤10的6次方) 名同学,每位同学都获得了两张卡,红卡或者黑卡。每张卡上都有一个不超过 10的9次方 的非负整数。第 i 位同学手里红卡数字是 ai ,黑卡数字是bi。
现在需要每位同学出牌。每位同学可以直接将红卡上的数字打出,或者将自己的红卡上的数字和自己黑卡数字进行按位异或操作后的结果打出。最后老师会收集所有同学打出的数字。
这些数字中出现次数最多的数字是众数。在所有同学合作的最优策略下,我们希望众数对应数字出现的次数尽可能多。请问出现次数最多的数字是多少呢?
输入格式
第一行,一个正整数 n。
接下来 n 行,其中第 i 行时非负整数 ai,bi 代表第 i 名同学手上红卡和黑卡的数字。
输出格式
一个整数,表示答案。如果有多个解,请输出最小的那个。
输入输出样例
输入 #1复制
4 21 9 28 9 28 3 17 4
输出 #1复制
21
说明/提示
样例解释:
众数出现次数最多是 3 次,有如下两种方法:
- 1 号同学直接出红卡,2号同学出红黑异或,3 号同学随便出,4 号同学出红黑异或。这样 1,2,4 号同学都可以打出 2121。
- 1 号同学出红黑异或,2 号同学直接出红卡,3 号同学直接出红卡,4号同学随便出。这样 1,2,3 号同学都可以打出 28。
所以 2121 和 2828 都是出现次数最多的众数,因为最多可以出现 3 次,不存在出现 4 次的方案。但是由于要求如果有多解输出小的,请输出 21。
#include <iostream>
using namespace std;
long long ans=0;
int a[10000010]={0};
//用数组的下标代表数字,下标对应存储的数字表示出现的次数
int n,temp;
int main()
{
int min=0,max=0;
cin>>n;
for(int i=0;i<n;i++){
int q,w;
cin>>q>>w;
if(q!=(q^w)) a[q]++;//如果两数不同,就有两种选择
a[q^w]++;//如果两数相同,就只相当于有一种选择
if(i==0)
{
min=q;
max=q;
}
if(q>max)
max=q;
if(q<min)
min=q;
if((q^w)>max)
max=(q^w);
if((q^w)<min)
min=(q^w);
}
for(int i=min;i<=max;i++){//找到所有中最小和最大的数字,减少循环次数,多用空间来节省时间
if(a[i]>ans){//当次数到达3之后就不会再更新数据了
ans=a[i];
temp=i;
}
}
cout<<temp;//输出最小的众数
return 0;
}