2007年分区联赛提高组之一 统计数字
Time Limit:1000MS Memory Limit:256000K
Description
某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。
Input
输入包含n+1行;
第一行是整数n,表示自然数的个数;
第2~n+1每行一个自然数。
Output
输出包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。
Sample Input
8
2
4
2
4
5
100
2
100
Sample Output
2 3
4 2
5 1
100 2
分析:
可哈希表 也可以直接暴力
数据不大 哈希的方法不难
暴力CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[200001];
int n,m;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
for(int i=1;i<=n;){
cout<<a[i]<<" ";
int sum=1;
int j=i+1;
while(a[i]==a[j]&&j<=n) j++,sum++;
i=j;
cout<<sum<<endl;
}
return 0;
}
哈希表CODE:
手动开了O2优化 极限卡时间 997MS
#include<iostream>
#include<cstdio>
#include<algorithm>
#define p 299993
#pragma GCC optimize(2)
using namespace std;
struct hashs{
int c,num;
}hash[p];
int n,s;
int hash2(int y){
return y%p; //哈希函数
}
int locate(int x){
int q=hash2(x),i=0;
while(i<p&&hash[(i+q)%p].c&&hash[(i+q)%p].c!=x) //定位
i++;
return (i+q)%p;
}
void ins(int x)
{
int w=locate(x);
hash[w].c=x;
hash[w].num++; //统计
}
bool cmp(hashs x,hashs y)
{
if (!x.num||!y.num) return x.num>y.num; //排序
return x.c<y.c;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&s);
ins(s);
}
sort(hash,hash+p-1,cmp);
int i=0;
while(hash[i].num!=0){
cout<<hash[i].c<<" "<<hash[i].num<<endl;
i++;
}
return 0;
}