PTA 5-14 电话聊天狂人 (25分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数NN(\le 10^5≤105),为通话记录条数。随后NN行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
/* * 就这道题而言:如果采取直接电话号码长度为11 直接排序O(11 * n * log n ) 然后在找出现最多的O(11 * n) 时间效率比采用散列表还要好点- - 1.上述方案在实际应用中不可行 应为会涉及到不断插入新号码的问题 每插入一个新号码都要重新进行排序。 可以考虑用散列表解决 这题哈希函数采用除留余数法 解决冲突采用分离链接法。 */ #include "iostream" #include "cmath" #include "cstring" using namespace std; #define KEYLENGTH 11 typedef char ElementType[KEYLENGTH]; typedef int Index; /* 散列地址类型 */ struct LNode { ElementType data; LNode* next; int count; }; typedef LNode *ptrToLNode; typedef ptrToLNode Position; typedef ptrToLNode List; typedef struct TblNode* HashTable; struct TblNode { /* 散列表节点定义 */ int tableSize; /* 表的大小 */ List heads; /* 指向链表头结点的数组 */ }; #define MAXTABLESIZE 1000000 int nextPrime(int n) { int i, p = (n % 2) ? n + 2 : n + 1; while (p < MAXTABLESIZE) { for (i = sqrt(p); i > 2; i--) if (!(p%i)) break; if (i == 2) break; else p += 2; } return p; } HashTable createTable(int tableSize) { HashTable h; int i; h = (HashTable)malloc(sizeof(struct TblNode)); h->tableSize = nextPrime(tableSize); h->heads = (List)malloc(h->tableSize* sizeof(struct LNode)); for (i = 0; i < h->tableSize; i++) { h->heads[i].data[0] = '\0'; h->heads[i].next = NULL; h->heads[i].count = 0; } return h; } int Hash(int p, int tableSize) { /* 设置映射的哈希函数 */ return p % tableSize; /* 采用除留余数法 */ } Position find(HashTable h , ElementType key) { Position p; Index pos; pos = Hash(atoi(key+KEYLENGTH-5),h->tableSize); /* 初始散列位置 */ p = h->heads[pos].next; /* 从该链表的第一个节点开始 */ while (p && strcmp(p->data, key)) /* 未到表尾 并且key未找到时 */ p = p->next; return p; } bool insert(HashTable h, ElementType key) { Position p, newCell; Index pos; p = find(h, key); if (!p) { newCell = (Position)malloc(sizeof(struct LNode)); strcpy(newCell->data, key); newCell->count = 1; pos = Hash(atoi(key + KEYLENGTH - 5), h->tableSize); /* 初始散列位置 */ /* 头插法 将newCell作为h->heads[pos]的第一个结点 */ newCell->next = h->heads[pos].next; h->heads[pos].next = newCell; return true; } else { p->count++; return false; } } void scanAndOutput(HashTable h) { int i, MaxCnt, PCnt; MaxCnt = PCnt = 0; ElementType MinPhone; List ptr; MinPhone[0] = '\0'; for (i = 0; i < h->tableSize; i++) { ptr = h->heads[i].next; while (ptr) { if (ptr->count > MaxCnt) { MaxCnt = ptr->count; strcpy(MinPhone, ptr->data); PCnt = 1; } else if (ptr->count == MaxCnt) { PCnt++; if (strcmp(MinPhone, ptr->data) > 0) strcpy(MinPhone, ptr->data); } ptr = ptr->next; } } cout << MinPhone << " "<< MaxCnt ; if (PCnt > 1) cout << " "<<PCnt; cout << endl; } void destroyTable(HashTable h) { int i; Position p, temp; for (i = 0; i < h->tableSize; i++) { p = h->heads[i].next; while (p != NULL) { temp = p->next; free(p); p = temp; } } free(h->heads); free(h); } int main() { int n, i; ElementType key; cin >> n; HashTable h = createTable(2 * n); for (i = 0; i < n; i++) { cin >> key; insert(h, key); cin >> key; insert(h, key); } scanAndOutput(h); destroyTable(h); return 0; }
此鸟不飞则已,一飞冲天,不鸣则已,一鸣惊人~~~ 我要做这只鸟儿~~ O(∩_∩)O哈!