5-14 电话聊天狂人 (25分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(
≤105
),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
思路
需要注意这每一条数据都是11位电话号码,所以要么longlong,要么char[],后者要用字符串比较函数,总的来说可能比直接的数字比较效率要低些。
下面的代码是二叉方法实现。现在想来,这些数据应该可以用hash表存储,能够最快映射找到某一个电话号码是否存在并后续操作。
点击访问 PTA-测验
#include<stdlib.h>
#include<stdio.h>
/*
时间 结果 得分 题目 编译器 用时(ms)内存(MB)用户
2016-03-16 20:17 部分正确 15 5-14 gcc 1 1 569985011
测试点 结果 得分/满分 用时(ms)内存(MB)
测试点1 答案正确 12/12 1 1
测试点2 答案正确 3/3 1 1
测试点3 答案正确 10/10 243 10
*/
typedef struct node *PNum;
struct node
{
long long a;
int times;
PNum Left,Rignt;
};
PNum Insert(PNum,long long);
void Print(PNum,long long*,int*,int*);
int main()
{
int n;
scanf("%d",&n);
n*=2;
long long phone;
PNum P=NULL;
for(int i=0; i<n; i++)
{
scanf("%lld",&phone);
P=Insert(P,phone);
}
int Times=0,Num;
long long MinPhone;
Print(P,&MinPhone,&Times,&Num);
printf("%lld %d",MinPhone,Times);
if(Num>1)printf(" %d",Num);
return 0;
}
void Print(PNum N,long long *MinPhone,int* Times,int *Num)
{
if(N)
{
Print(N->Left,MinPhone,Times,Num);
if(N->times>*Times)
{
*MinPhone=N->a;
*Num=1;
*Times=N->times ;
}
else if(N->times ==*Times)
{
++*Num;
}
Print(N->Rignt,MinPhone,Times,Num);
}
}
PNum Insert(PNum N,long long X)
{
if(!N)
{
PNum NewP=(PNum)malloc(sizeof(struct node));
NewP->a=X;
NewP->times =1;
NewP->Left =NULL;
NewP->Rignt =NULL;
return NewP;
}
if(N->a>X)
{
N->Left =Insert(N->Left ,X);
}
else if(N->a<X)
{
N->Rignt =Insert(N->Rignt ,X);
}
else
{
++N->times;
}
return N;
}