Output
输出包括两个部分,第一个部分是错误的电话号码,对于这些号码应当按照输入的顺序以原始的形式输出。在输出错误电话号码前输出Error:
,随后输出这些号码,如果没有错误的电话号码,则输出Not found.
第二部分是重复的正确的电话号码,对每一个在电话簿中以任何形式出现一次以上的电话号码,生成一行输出。这一行应以标准形式给出电话号码,其后跟随一个空格,空格后跟随电话号码在电话簿中出现的次数。所有重复的电话号码输出行应以号码的升序排列(小号码在前)。在输出重复电话号码前输出Duplication
,随后按照上述格式输出号码,如果在输入中没有重复的电话号码,则输出:Not found.
Note
你所编写的程序以后可能会在一种特殊的嵌入式设备上运行,为了降低成本,这种设备使用的 CPU 不是很快、可用的 RAM 为 288K(跟 GBA 一样)且它没有磁盘设备因此不能使用文件作为数据的临时存储。
Hint
请参考《编程珠玑》第一部分,若程序不能在规定的内存中运行,则不得分。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 512KB | 0 |
测试用例 2 | 以文本方式显示
| 以文本方式显示
| 1秒 | 512KB | 0 |
电话号码合法性的判断和输出就不讲了,只要在到判断到非法时直接输出即可。
这道题由于这道题的内存卡得很死,所以在记录号码是否记录过时 用bitset,每 一个位 (0或1)记录一个号码的状态。又因为合法的号码必须是3或6,所以最多2000000个 bit 就能记录下所有合法号码的状态。0代表号码未访问过,1代表号码已经访问。
对于已经访问过的号码,就存入哈希表中,如果已经存入哈希表中了,那就将出现次数增加
这样存储的话:【 (2000000/8) + (4+2)*1505 + 4*21】/1024 = 253KB 再加上其他定义的一些int变量,这个空间也是完全够用的。
几个注意点:
1.用char [ ] 来获取输入字符串,而不是string,因为string会占用额外的空间
2.将字母与数字映射时,最好不要用map,可以写个switch函数来判断,虽然慢点,但是不占空间
3.在判断完是否合法后,不合法直接输出,合法的话,转换成int类型,因为继续用字符串保存的话占用空间更大。
4.对于排序:直接用sort,写一个cmp函数就行
#include <bits/stdc++.h>
using namespace std;
int dc = 0;
bitset<1000000> arr[2];
struct mymap {
int num;
short c;
} d[1505];
bool cmp(mymap a, mymap b) {
return a.num < b.num;
}
int getNumber(char ch) {
switch (ch) {
case 'A': case 'B': case 'C':
return 2;
case 'D': case 'E': case 'F':
return 3;
case 'G': case 'H': case 'I':
return 4;
case 'J': case 'K': case 'L':
return 5;
case 'M': case 'N': case 'O':
return 6;
case 'P': case 'R': case 'S':
return 7;
case 'T': case 'U': case 'V':
return 8;
case 'W': case 'X': case 'Y':
return 9;
default:
return -1; // 返回 -1 处理无效字符
}
}
void insert(int a) {
int pos = a % 1503;
while(1){
if (d[pos].num == 0 && d[pos].c == 0) {
d[pos].num = a;
d[pos].c = 2;
dc++;
return;
} else if (d[pos].num == a) {
d[pos].c++;
return;
} else {
pos = (pos + 1) % 1503;
}
}
}
int main() {
char temp[21];
int num, len, begin, c, w;
int i, flag = 0;
printf("Error:\n");
while (cin.getline(temp, 21)) {
num = 0;
len = strlen(temp);
begin = 0;
c = w = 0;
if(temp[0]=='\0'){
break;
}
// 去除前面的 '-'
while (temp[begin] == '-') {
begin++;
}
if (begin == len) {
flag = 1;
cout << temp << endl;
continue;
}
if (temp[begin] == '3' || getNumber(temp[begin]) == 3) {
w = 0;
} else if (temp[begin] == '6' || getNumber(temp[begin]) == 6) {
w = 1;
}
if (temp[begin] == '3' || getNumber(temp[begin]) == 3 ||
temp[begin] == '6' || getNumber(temp[begin]) == 6) {
for (i = begin + 1; i < len; i++) {
if (temp[i] == '-') {
continue;
} else {
c++;
if (temp[i] >= '0' && temp[i] <= '9') {
num = num * 10 + (temp[i] - '0');
} else {
int number = getNumber(temp[i]);
if (number >= 0 && number <= 9) {
num = num * 10 + number;
} else {
flag = 1;
cout << temp << endl;
break;
}
}
}
}
if (i == len && c != 6) {
flag = 1;
cout << temp << endl;
continue;
}
if (i == len) {
if (arr[w].test(num)) {
insert((w + 1) * 3000000 + num);
} else {
arr[w].set(num);
}
}
} else {
flag = 1;
cout << temp << endl;
}
}
if (flag == 0) {
printf("Not found.\n");
}
printf("\nDuplication:\n");
sort(d, d + 1505, cmp);
for (int k = 1505 - dc; k < 1505; ++k) {
printf("%03d-%04d %d\n", d[k].num / 10000, d[k].num % 10000, d[k].c);
}
if (dc == 0) {
printf("Not found.\n");
}
return 0;
}