问题 : 众数
时间限制 : 1.000 sec 内存限制 : 128 MB
题目描述
给出N个1到30000间无序正整数,其中1≤N≤30000,同一个正整数可能会出现多次,出现次数最多的整数称为众数。求出数列中的众数及它出现的次数。
输入
两行,第一行为正整数的个数N,第二行为n个正整数。
输出
有若干行,每行两个数,第一个是众数,第二个众数出现的次数。若有多个众数,则按数从小到大逐行输出。
样例输入 Copy
12
2 4 2 3 2 5 3 7 2 3 4 3
样例输出 Copy
2 4
3 4
分治法求众数
#include<iostream>
#include<algorithm>
using namespace std;
int a[30000]; //众数的值
int b[30000]; //众数的重数
int c[30000];
int split(int l,int r,int k) //分治算法
{
int max=0;//记录重数的最大值
int i=l; //记录原来的l位置
int j=r; //记录原来的r位置
int mid=(l+r)/2;
a[k]=c[mid];
// printf("%d ",mid);
for(; l<mid&&c[l]!=c[mid]; l++); //寻找众数的最左边
//printf("%d ",l);
for(; r>mid&&c[r]!=c[mid]; r--); //寻找众数的最右边
//printf("%d ",r);
b[k]=r-l+1;//经过两个for循环后,众数个数就是r-l+1
if(b[k]>max)
max=b[k];
if(l-i>=b[k]) //剪枝
{
k++;
split(i,l-1,k);
}// 对左边部分分治
if(j-r>=b[k])//剪枝
{ k++;
split(r+1,j,k); // 对右边部分分治
}
return max;
}
int main()
{
int nn,i,j;
int max;
scanf("%d",&nn);
for(i=0; i<nn; i++)
scanf("%d",&c[i]);
sort(c,c+nn); //先排序,方便统计众数个数
int l=0;
int k=0;
int r=nn-1;
max=split(l,r,k);
int n,m,temp;
for(n=0;n<=k;n++)
for(m=n;m<=k;m++)
{
if(a[m]>a[m+1])
{
temp=a[m];
a[m]=a[m+1];
a[m+1]=temp;
temp=b[m];
b[m]=b[m+1];
b[m+1]=temp;
}
}
int nnn=0;
for(i=0;i<nn;i++)
{
if(b[i]==max)
{
nnn++;
if(nnn==1)
{
printf("%d %d",a[i],b[i]);
}
else
{
printf("\n");
printf("%d %d",a[i],b[i]);
}
}
}
}