这是一题来自AR的,令我受益匪浅的题:AR的众数
具体的受益就是:遇到卡时空的题永远不要开流和憨批头文件,太憨了,辣鸡cin、cout。
三个思路:
- 最无脑暴力的逐个元素标记法。
- 排序后,第n/2个必是众数。
- 众数抵消。
逐元素标记法:
该数据值域较大,保序离散化可做。
#include <stdio.h>
#include <algorithm>
using namespace std;
int a[1005], b[1005], c[1005];
int main()
{
int res = 0, cnt = 0, num;
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
b[i]=a[i];
}
sort(b,b+n);
int m = unique(b,b+n)-b;
for(int i = 0; i < n; i++){
a[i] = lower_bound(b,b+m,a[i])-b;
c[a[i]]++;
}
for(int i = 0; i < n; i++){
if(c[a[i]]>n/2){
printf("%d", b[a[i]]);
break;
}
}
return 0;
}
排序法:
#include <stdio.h>
#include <algorithm>
using namespace std;
int a[1005];
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
sort(a,a+n);
printf("%d", a[n/2]);
return 0;
}
众数抵消:
思路分析:利用众数出现的次数>n/2,必然能和非众数一一抵消后仍然留有标记。所以,当输入完毕后,最后一个被标记着的元素就是众数。
#include <stdio.h>
int main()
{
int res = 0, cnt = 0, num;
int n;
scanf("%d", &n);
while(n--){
scanf("%d", &num);
if(cnt == 0){
res = num;
++cnt;
}else if(res == num)
++cnt;
else
--cnt;
}
printf("%d", res);
return 0;
}