您的位置:首页 > 其它

Mode用cin的不超时程序

2016-02-15 19:34 190 查看
问题描述
小明最近在上数学课,老师给小明布置了个作业:在n个数里找出所有的众数。
众数的定义是这样的:在所有数当中出现次数最多的数被称为众数。并且根据定义,众数有可能有多个。
你能解决这个问题吗?
输入格式
第一行一个整数n。
第二行有n个整数,ai表示第i个数。
输出格式
输出一行,包括一个整数k,表示众数的个数。
接下来一行包括k个整数,每个整数都表示一个众数,并且从小到大输出。
输入样例:
10
3 3 3 2 3 1 2 2 1 2

输出样例:
2
2 3
数据范围
40%的数据,1<=n<=400
100%的数据,1<=n<=1000000,1<=ai<=1000000000

在像Mode这样的题目面前,cin的效率饱受摧残。在上百万个数的面前,其时间几乎都是比scanf慢上很多。但是如果提高其他部分的效率,也许这也不是不可能。我用cin过了Mode。很奇怪,这是为什么呢?
答案就是:我用了一次排序加单次线性遍历。首先的一次排序用了sort(),接下来的遍历是最复杂也是最关键的。在程序中,nowNum表示目前正在访问的这一段数,如果当前数与nowNum不同,则应该更新nowNum,也就是进入了另一段数中。nowMax表示目前这一段数的长度,如果nowNum与当前数相同,则其应该加1,而allMax表示全局最长,当nowMax大于它的时候更新为nowMax。ans数组存储当前的答案,nm为其长度,nm=0相当于清空整个数组,这在nowMax>allMax,需要更新全局众数的时候使用。最后当然就是输出答案了,这个很简单。算来这个程序中最大的还只是那个sort()呢。
#include <fstream>
#include <iostream>
#include <algorithm>
using namespace std;
long long int mode[1000001];
int main(){
int n;
cin>>n;
for (int i=0;i<n;++i){ cin>>mode[i]; }

sort(mode+0,mode+n);

int nowMax=0,allMax=0;
long long int ans[100001];
int nm=0;
int nowNum=mode[0];
for (int i=0;i<n;++i){
if (nowNum!=mode[i]){ nowNum=mode[i]; nowMax=0; }
if (nowNum==mode[i]){ ++nowMax; }
if (nowMax>allMax){ allMax=nowMax; nm=0; }
if (nowNum==mode[i] && nowMax==allMax){ ans[nm]=mode[i]; ++nm; }
}
cout<<nm<<endl;
for (int i=0;i<nm;++i){
cout<<ans[i]<<' ';
}
cout<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: