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;
}
嗯,就这样了...