您的位置:首页 > 其它

POJ1002 487-3279

2013-07-30 16:41 357 查看
题目来源:http://poj.org/problem?id=1002

题目大意:

  (背景)企业喜欢容易被人记住的电话号码。使一个电话号码容易被记住的一种方法是让它“拼”(spell)出来是一个好记的单词或短语(与手机键盘上的字母联系起来)。比如,你可以拨打好记的TUT-GLOP打电话给滑铁卢大学。有时,也可以只让号码的一部分拼成一个单词。当你晚上回到宾馆,你可以拨打310-GINO从Gino's订一份披萨。另一种让号码好记的方式是将号码分成好记的组。比如,你可以打“3个10”电话3-10-10-10订必胜客的pizza。

  电话号码的标准形式是一个7位的十进制数字,前三位与后四位之间用短横线隔开。(如888-1200)。电话键盘提供了从字母到数字的映射规则:

  A B C -> 2

  D E F -> 3

  G H I -> 4

  J K L -> 5

  M N O -> 6

  P R S -> 7

  T U V -> 8

  W X Y -> 9

  其中,不含字母Q和Z的映射。短横线可以被添加或删除。TUT-GLOP的标准形式为888-4567,310-GINO的标准形式为310-4466,3-10-10-10的标准形式为310-1010.

  如果两个号码的标准形式相同,那么我们认为这两个号码是相同的。

  你的公司在为本地商人们编辑一个电话号码薄,作为质量控制的一部分,你希望检查号码薄中是否存在相同的号码。

  输入:测试数据仅含一个样例。第一行为一个正整数,为号码个数(最大到100,000)。接下来的每行为号码薄中的一个号码。号码可能含有数字、字母(大写,不含A和Z)和短横线。数字和字母的个数为7.

  输出:每行输出一个出现多次的电话号码的标准形式,空格后输出该号码出现了多少次。按号码的升序输出。若没有重复号码输出一行文字:“No duplicates.”

Sample Input

12
4873279
ITS-EASY
888-4567
3-10-10-10
888-GLOP
TUT-GLOP
967-11-11
310-GINO
F101010
888-1200
-4-8-7-3-2-7-9-
487-3279

Sample Output

310-1010 2
487-3279 4
888-4567 3


测试数据:http://acm.student.cs.uwaterloo.ca/~acm00/regionals/

     Contest Data -> Real -> Testing data and solutions -> E

解题关键:

  1.建立字母->数字之间的映射关系

  2.按映射关系进行映射,将所有号码转换为标准形式

  3.将所得的标准形式进行排序和统计,输出统计结果

最开始用Java的HashMap做,发现内存和时间都大得惊人。所以这是第一次,可能也是最后一次用Java刷题了吧。

//////////////////////////////////////////////////////////////////////////
//        POJ1002 487-3279
//        Memory: 596K        Time: 329MS
//        Language: C++        Result: Accepted
//////////////////////////////////////////////////////////////////////////

#include <cstdio>
#include <algorithm>

using namespace std;

int main(void) {
int n;
scanf("%d", &n);
int no = n;
int * ans = new int
;
while(no--) {
char buff[50];
char c;
int stdForm = 0;
int i = 0;
scanf("%s", buff);
//转换为标准形式
while ((c = buff[i++]) != '\0') {
if (c >= '0' && c <= '9') {
stdForm = stdForm * 10 + c - '0';
} else if (c >= 'A' && c < 'Q') {
stdForm = stdForm * 10 + (c - 'A') / 3 + 2;
} else if (c > 'Q' && c < 'Z') {
stdForm = stdForm * 10 + (c - 'A' - 1) / 3 + 2;
}
}
ans[no] = stdForm;
}
sort(ans, ans + n);
bool flag = false;
int cnt = 1;
//统计&输出
for (int i = 0; i < n; ++i) {
if (i + 1 == n) {
if (cnt != 1) {
printf("%03d-%04d %d\n", ans[i] / 10000, ans[i] % 10000, cnt);
}
} else if (ans[i + 1] == ans[i]) {
++cnt;
flag = true;
} else {
if (cnt != 1) {
printf("%03d-%04d %d\n", ans[i] / 10000, ans[i] % 10000, cnt);
cnt = 1;
}
}
}
if (flag == false) {
printf("No duplicates.\n");
}
system("pause");
return 0;
}


View Code
我大概也就能优化成这样了,有大牛的实现30ms内完成,只能膜拜。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: