题意
题目的意思是,把字母,短线,数字组成的电话号码,换成相应的纯数字号码(中间最后需要加一条短线),再计算有无重复的,没重复的输出”No duplicates.”, 有重复的输出电话号码和重复次数。
分析
简单的来讲有两种思路:
第一是申请长度10000000的整型数组,下标用来存储电话,数组记录重复次数,最后直接输出有重复的号码。
第二是申请长度为100000的数组,数组存储号码,最后排序输出即可。
下面的代码是第二种思路,原因是第一种虽然实现简单,但耗费了很多不必要的空间,而且性能并未提高。排序直接用的库函数sort,所以时间耗费还比较多,有待优化。
Memory: 600K Time: 391MS Length:38LINES
#include<iostream>
#include<algorithm>
using namespace std;
int arrayResult[100000] = { 0 };
int main()
{
int MapRela[26]; //先对字母和数字做一个映射
MapRela['A' - 65] = 2; MapRela['L' - 65] = 5; MapRela['M' - 65] = 6; MapRela['N' - 65] = 6; MapRela['O' - 65] = 6; MapRela['P' - 65] = 7;
MapRela['R' - 65] = 7; MapRela['S' - 65] = 7; MapRela['T' - 65] = 8; MapRela['V' - 65] = 8; MapRela['U' - 65] = 8; MapRela['W' - 65] = 9;
MapRela['X' - 65] = 9; MapRela['Y' - 65] = 9; MapRela['B' - 65] = 2; MapRela['C' - 65] = 2; MapRela['D' - 65] = 3; MapRela['E' - 65] = 3;
MapRela['F' - 65] = 3; MapRela['G' - 65] = 4; MapRela['H' - 65] = 4; MapRela['I' - 65] = 4; MapRela['J' - 65] = 5; MapRela['K' - 65] = 5;
int Amount = 0;
fscanf(stdin, "%d", &Amount); //用fscanf和下面的fgets在输入效率上会高一些。
getchar(); //跳过换行符
for (int cnt = 0; cnt < Amount; ++cnt)
{
char tempnumber[100] = { 0 }; //字符串长度并未告知,所以取大一点
fgets(tempnumber, 100, stdin);
int k = 0;
for (int i = 0; i < strlen(tempnumber); ++i)
{
if (tempnumber[i] >= 65) k = k * 10 + MapRela[tempnumber[i] - 65];
else if (tempnumber[i] >= 48) k = k * 10 + tempnumber[i] - 48;
}
arrayResult[cnt] = k;
}
sort(arrayResult, arrayResult + Amount);
int key = 0;
for (int i = 0; i < Amount;)
{
int count = 1;
for (int j = i; j != Amount - 1 && arrayResult[j] == arrayResult[j + 1]; ++j, ++count);
if (count > 1 && (key = 1)) printf("%03d-%04d %d\n", arrayResult[i] / 10000, arrayResult[i] % 10000, count);
i += count;
}
if (!key) cout << "No duplicates." << endl;
return 0;
}