11-散列1 电话聊天狂人
11-散列1 电话聊天狂人(25 分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤105),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
开始使用冲突处理方法采用平方探测法,散列方法先后尝试了平方取中法和求余法,前者因为电话号码位数过长计算其平方无法存储,后者冲突次数过多导致超时。
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int TableSize = 10000;
struct HushUnit{
long long Tel = -1;
int times = 0;
};
int Prime(int n){
int mark = 1;
for(int i=2;i<sqrt(n);i++){
if(!n%i) mark = 0;
}
return mark;
}
int getTsize(int n){
while(!Prime(n)) n++;
return n;
}
/*平方取中法 电话号码太长 平方后超出存储范围
int hush(long long a){
long long sq = a*a;
if(sq < 0) sq = -sq;
cout<<sq<<endl;
long long sq_cp = sq;
int i,cnt = 1,n = 3,p = 0,TableSize = getTsize(TableSize);
while(sq_cp/10){
cnt++;
sq_cp /= 10;
}
int start = cnt/2 - 1;
while(start){
sq /= 10;
start--;
}
for(i=0;i<3;i++){
p += (int)pow(10,i)*(sq%10);
sq /= 10;
}
return p;
}*/
int hush(long long a){
return (int)a % TableSize;
}
void Insert(HushUnit HushTab[],long long tel){
int cnt = 0,Pos = hush(tel);
while(HushTab[Pos].Tel > 0 && HushTab[Pos].Tel != tel){
if(++cnt % 2){
Pos += (cnt + 1)/2*(cnt + 1)/2;
while(Pos >= TableSize) Pos -= TableSize;
}
else{
Pos -= cnt/2 * cnt/2;
while(Pos < 0) Pos += TableSize;
}
}
HushTab[Pos].Tel = tel;
HushTab[Pos].times++;
}
int main(){
int i,n,cnt,most_times = 0;
HushUnit HushTab[TableSize];
long long a,b,most = pow(10,12);
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%lld %lld",&a,&b);
Insert(HushTab,a);
Insert(HushTab,b);
}
for(i=0;i<TableSize;i++){
if(HushTab[i].times > 0){
if(HushTab[i].times > most_times){
cnt = 1;
most = HushTab[i].Tel;
most_times = HushTab[i].times;
}
else if(HushTab[i].times == most_times){
cnt++;
if(HushTab[i].Tel < most) most = HushTab[i].Tel;
}
}
}
cout<<most<<" "<<most_times;
if(cnt == 1) cout<<endl;
else cout<<" "<<cnt<<endl;
return 0;
}
冲突处理方法换成分离链接法,第三个测试点一直段错误,始终找不到bug,先放这儿吧。#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int TableSize;
struct Unit{
long long Tel = -1;
int times = 0;
struct Unit *next = NULL;
};
int Prime(int n){
int mark = 1;
for(int i=2;i<sqrt(n);i++){
if(n%i == 0) mark = 0;
}
return mark;
}
int getTsize(int n){
while(!Prime(n)) n++;
return n;
}
int hush(long long a){
return (int)a % TableSize;
}
void Insert(Unit* HushTab[],long long tel){
int Pos = hush(tel);
Unit *node = HushTab[Pos];
while(node != NULL && node->Tel != tel) node = node->next;
if(node == NULL){
Unit *newNode = new Unit;
newNode->Tel = tel;
newNode->times++;
newNode->next = HushTab[Pos]->next;
HushTab[Pos]->next = newNode;
}
else node->times++;
}
int main(){
int i,n,cnt,most_times = 0;
scanf("%d",&n);
TableSize = getTsize(2*n);
Unit* HushTab[TableSize];
for(i=0;i<TableSize;i++) HushTab[i] = new Unit;
long long a,b,most = pow(10,12);
for(i=0;i<n;i++){
scanf("%lld %lld",&a,&b);
Insert(HushTab,a);
Insert(HushTab,b);
}
for(i=0;i<TableSize;i++){
Unit *node = HushTab[i]->next;
while(node != NULL){
if(node->times > most_times){
cnt = 1;
most = node->Tel;
most_times = node->times;
}
else if(node->times == most_times){
cnt++;
if(node->Tel < most) most = node->Tel;
}
node = node->next;
}
}
cout<<most<<" "<<most_times;
if(cnt == 1) cout<<endl;
else cout<<" "<<cnt<<endl;
return 0;
}
Email:JingwangLi@outlook.com