NOIP2007 统计数字

题意简化

传送门
给你n个数 (有相同的) ,从小到大输出每个数重复出现的次数
值域1.5*1e9 , n<=2e5

题解

看到这样的题,最先想到的,复杂度最优的肯定是桶排序
但是,值域是1500000000,桶肯定是开不下的
所以我们再想,桶有什么缺点呢???
就是会出现很多空桶!!!
这些空桶大大浪费了空间
所以我们不妨考虑直接排遍序
然后相同的数肯定就在一起了
然后统计每段连续的数的个数就好了

代码

#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
#define get getchar()
#define in inline
in int read()
{
	int t=0; char ch=get;
	while(ch<'0' || ch>'9') ch=get;
	while(ch<='9' && ch>='0') t=t*10+ch-'0',ch=get;
	return t;
} //快读
struct num{
	int id,sum;
}a[200010]; //每个数出现的次数及它的值
int tot,n,h[200010]; //tot表示有多少个不同的数, h为初始序列
int main()
{
	n=read(),a[0].id=-199; //初始化
	for(re int i=1;i<=n;i++)
		h[i]=read();  //输入
	sort( h+1,h+n+1); //按从小到大排序
	for(re int i=1;i<=n;i++)
	{
		if(a[tot].id==h[i])a[tot].sum++; //如果当前数与之前的数相同,则将之前数的个数+1
		else a[++tot].id=h[i],a[tot].sum=1; //如果不同,则将不同的数的总数+1,然后赋值
	}
	for(re int i=1;i<=tot;i++)
		cout<<a[i].id<<' '<<a[i].sum<<endl; //输出
	return 0;
}

嗯,就这样了...
原文地址:https://www.cnblogs.com/yzhx/p/10699776.html