07noip 统计数字 解题报告

题目描述 Description

【问题描述】
某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109)。已知不相同的数
不超过10000 个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统
计结果。

输入描述 Input Description

第1行是整数n,表示自然数的个数。
第2~n+1 行每行一个自然数。

输出描述 Output Description

输出包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大
的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。

样例输入 Sample Input

8
2
4
2
4
5
100
2
100

样例输出 Sample Output

2 3
4 2
5 1
100 2

数据范围及提示 Data Size & Hint

【限制】
40%的数据满足:1<=n<=1000
80%的数据满足:1<=n<=50000
100%的数据满足:1<=n<=200000,每个数均不超过1 500 000 000(1.5*10^9)

  这道题目并不难,但是它却成功让我TLE了。这个题目最正确的思路是全部读进来,然后排序统计个数。但是我很坚定的要一边读入一遍插排,然后TLE掉。最后还万般悲苦的写了一个二叉查找树,虽然这棵树不怎么平衡,可题目还是100ms内解决掉了。  

  当然,放代码肯定不能放我那个渣的不行的二叉查找树。

 1 program number;
 2 var
 3  i,k,t,n:longint;
 4  a:array[1..200000]of longint;  //放置读入数据
 5  b,c:array[0..10000]of longint; //放置所有数字和出现次数
 6 
 7 procedure qsort(h,t:longint);  //排序
 8 var
 9  i,j,x,k:longint;
10 begin
11  i:=h;
12  j:=t;
13  x:=a[(h+t) div 2];
14  while (i<j) do
15   begin
16   while (a[i]<x) do inc(i);
17   while (a[j]>x) do dec(j);
18   if (i<=j) then
19    begin
20    k:=a[i];
21    a[i]:=a[j];
22    a[j]:=k;
23    inc(i);
24    dec(j);
25    end;
26   end;
27  if (i<t) then qsort(i,t);
28  if (h<j) then qsort(h,j);
29 end;
30 
31 begin
32  readln(n);
33  for i:=1 to n do
34   readln(a[i]);
35  qsort(1,n);
36  t:=0;
37  for i:=1 to n do  //统计数字
38   if a[i]=b[t] then
39    inc(c[t]) else
40    begin
41    inc(t);
42    b[t]:=a[i];
43    c[t]:=1;
44    end;
45  for i:=1 to t do
46   writeln(b[i],' ',c[i]);
47 end.

 

posted @ 2014-10-22 14:37  Xstsow  阅读(255)  评论(0编辑  收藏  举报