7-14 电话聊天狂人
7-14 电话聊天狂人(25 分)
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤105),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
思路:使用结构体数组来存取,每次输入查找数组中是否存在,不存在则插入,否则个数加一,但是当N最大且随机时,运行超时。改成map也超时了!百度了下别人家的算法,我看见用二叉的都过了,我就想说难道二叉不是全部遍历了一遍嘛?!然后散列表我没有试但是我发现AC的都是用的char[]或者long long类型,然后改了下问题果然出在这里,一改就AC了,说map超时的朋友不好意思了哦
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; struct Node{ long long numb; int n; }a[200005]; bool cmp(Node a, Node b) { return a.n > b.n; } int main() { int n, sum = 0; cin >> n; for (int i = 0; i < n; i++) { long long numb1, numb2; cin >> numb1 >> numb2; int flag = 1; for (int i = 0; i < sum;i++) if (a[i].numb == numb1){ a[i].n++; flag = 0; break; } if (flag){ a[sum].numb = numb1; a[sum].n = 1; sum++; } flag = 1; for (int i = 0; i < sum; i++) if (a[i].numb == numb2){ a[i].n++; flag = 0; break; } if (flag){ a[sum].numb = numb2; a[sum].n = 1; sum++; } } sort(a, a + sum, cmp); int flag = 1; long long min = a[0].numb; for (int i = 1; i < sum; i++) { if (a[i].n != a[0].n)break; flag++; if (a[i].numb < min)min = a[i].numb; } if (flag == 1)cout << a[0].numb << " " << a[0].n << endl; else cout << min << " " << a[0].n << " " << flag << endl; return 0; }
#include<stdio.h> #include<map> #include<string> #include<algorithm> #include<iostream> using namespace std; int main() { map<string, int>ma; map<string, int>::iterator iter; int n; cin >> n; for (int i = 0; i < n; i++) { string str1, str2; cin >> str1 >> str2; iter = ma.find(str1); if (iter == ma.end()) ma.insert(pair<string, int>(str1, 1)); else ma[str1]++; iter = ma.find(str2); if (iter == ma.end()) ma.insert(pair<string, int>(str2, 1)); else ma[str2]++; } //map没有sort函数就有点儿不完美了 int max = 0, flag = 1; string str; for (iter = ma.begin(); iter != ma.end(); iter++) { if (iter->second == max) flag++; if (iter->second > max){ flag = 1; max = iter->second; str = iter->first; } } if (flag == 1) cout << str << " " << max << endl; else cout << str << " " << max << " " << flag << endl; return 0; }
#include<stdio.h> #include<map> #include<algorithm> #include<iostream> using namespace std; int main() { map<long long, int>ma; map<long long, int>::iterator iter; int n; cin >> n; for (int i = 0; i < n; i++) { long long numb1, numb2; cin >> numb1 >> numb2; iter = ma.find(numb1); if (iter == ma.end()) ma.insert(pair<long long, int>(numb1, 1)); else ma[numb1]++; iter = ma.find(numb2); if (iter == ma.end()) ma.insert(pair<long long, int>(numb2, 1)); else ma[numb2]++; } //map没有sort函数就有点儿不完美了 int max = 0, flag = 1; //max用来标记电话重复出现的最高次数,flag用来标记狂人重复的次数, long long numb; //用来记录最小狂人的号码 for (iter = ma.begin(); iter != ma.end(); iter++) { if (iter->second == max) flag++; if (iter->second > max){ flag = 1; max = iter->second; numb = iter->first; } } if (flag == 1) cout << numb << " " << max << endl; else cout << numb << " " << max << " " << flag << endl; return 0; }