- 题目地址
- 题目解析:分析见中国MOOC数据结构,我这里将依次给出1、排序后统计解法,2、不完整的Hash解法(没有查找功能),3、C++中的map解答(最后一个测试点超时)4、C++中的unorder_map解答
- 我的代码:
1、排序后统计
#include<stdio.h>
#include<stdlib.h>
int cmp(const void * a, const void * b)//注意使用的>,排序从小至大
{
return *(long long int *)a > *(long long int *)b;
}
int main()
{
int n, bb[200000];
static long long int aa[200000];//也可使用char处理
scanf("%d", &n); n *= 2;//成对输入
for (int i = 0; i < n; i++)
{
scanf("%lld", &aa[i]);
bb[i] = 1;//每个且不论重复的号码,均记录1次存在
}
qsort(aa, n, sizeof(long long int), cmp);
int max = 1;
for (int i = 1; i < n; i++)//后者若与前者相同,则后者=前者+1
if (aa[i] == aa[i - 1])
{
bb[i] = bb[i - 1] + 1;
if (bb[i] > max)
max = bb[i];
}
int cnt = 0;
for (int i = 0, flag = 1; i < n; i++)
if (bb[i]==max)
{
cnt++;
if (flag)//输出max中最小号码
{
printf("%lld ", aa[i]);
flag--;
}
}
printf("%d", max);
if (cnt>1)
printf(" %d", cnt);
return 0;
}
2、不完整Hash(没有查找功能)
#include<stdio.h>
#include<string.h>
char aa[500000][12] = { '\0' };
int n, bb[500000] = { 0 }, max = 0;
void insertHash(char * val, int key);
//这里的计算法利用11位电话后6位,若6位的首位大于4则-5,用作键名
//由于6位的首位被改变,则利用前6位(第6个即可能被-5那位),来保证存储值唯一
//由于装填因子最大为0.4,故采用线性探测法解决冲突
int main()
{
scanf("%d", &n);
char ss[12] = { '\0' };
for (int i = 0, key, ki = 1; i < n * 2; i++, ki = 1)
{
scanf("%s", ss);
//键名计算
key = (ss[5] - '0') > 4 ? ss[5] - '0' - 5 : ss[5] - '0';
while (ki < 6)
key = key * 10 + ss[5 + ki++] - '0';
insertHash(ss, key);
}
int cnt = 0;
for (int i = 0; i < 500000; i++)
if (bb[i] == max)
{
cnt++;
if (cnt == 1)
strcpy(ss, aa[i]);
else if (strcmp(ss, aa[i]) > 0)
strcpy(ss, aa[i]);
}
printf("%s %d", ss, max);
if (cnt > 1)
printf(" %d", cnt);
return 0;
}
void insertHash(char * val, int key)
{
while (aa[key][0] != '\0' && strcmp(aa[key], val))
{
if (key + 1 < 500000)
key++;
else
key = 0;
}
if (aa[key][0] == '\0')
strcpy(aa[key], val);
bb[key]++;
if (bb[key] > max)
max = bb[key];
return;
}
3、C++_map(最后一个测试点超时)
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
int n, max = 0, cnt = 0;
map<string, int>m;
scanf("%d", &n); n *= 2;
string ss;
for (int i = 0; i < n; i++)
{
cin >> ss;//string只能使用cin cout处理
if (!m.count(ss))//利用count查看是否存在
m[ss] = 0;
m[ss]++;
if (m[ss]>max)
max = m[ss];
}
for (auto it = m.begin(); it != m.end(); it++)
if (it->second==max)
{
cnt++;
if (cnt==1)
ss = it->first;//c++_string真方便
}
cout << ss;
printf(" %d", max);
if (cnt>1)
printf(" %d", cnt);
return 0;
}
4、C++_unorder_map
#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;
int main()
{
int n, max = 0, cnt = 0;
unordered_map<string, int>m;
scanf("%d", &n); n *= 2;
string ss;
for (int i = 0; i < n; i++)
{
cin >> ss;
if (!m.count(ss))
m[ss] = 0;
m[ss]++;
if (m[ss]>max)
max = m[ss];
}
for (auto it = m.begin(); it != m.end(); it++)
if (it->second==max)
{
cnt++;
if (cnt==1)
ss = it->first;
if (ss> it->first)//因为为无向图,故需找到max的最小号码,string真香
ss = it->first;
}
cout << ss;
printf(" %d", max);
if (cnt>1)
printf(" %d", cnt);
return 0;
}