题目大意:为了方便记忆,某地区的电话号可以用多种方式书写,如310-GINO,3-10-10-10等,即字母、数字、连字符,当然,每个字母可以映射到一个数字,题中已给出。输入一堆各种形式的电话号,让你求出有没有重复的电话号,有的话按字母表顺序输出电话号和重复次数,没有就输出“No duplications”。
思路:比较简单,把字母转换成数字,去掉连字符,用map记录重复次数即可。
下面的代码很容易理解,转自:http://www.cnblogs.com/HpuAcmer/archive/2012/04/19/2456986.html
1002 | Accepted | 5180K | 1297MS | C++ | 1090B |
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <iterator>
using namespace std;
char a[26]= {"2223334445556667777888999"};
int main()
{
map<string,int> m;
map<string,int>::iterator iter;
string s,t;
int n,j,len;
scanf("%d",&n);
do
{
cin>>s;
len = s.length();
for(j = 0 ; j < len ;++j)
{
if(s[j] <= 'Z' && s[j] >= 'A')
t.push_back(a[s[j] - 'A']);
else
{
if(s[j] != '-')
t.push_back(s[j]);
}
}
t.insert(3,1,'-');
m[t]++;
t.clear();
}while(--n);
bool dup = false;
for(iter = m.begin();iter != m.end(); ++iter)
if(iter->second > 1)
{
dup = true;
cout<<iter->first<<" "<<iter->second<<endl;
}
if(!dup)
puts("No duplicates.");
return 0;
}
最近看了《短码之美》,还有惯性,我把代码稍微改了一下。
1002 | Accepted | 5180K | 1282MS | C++ | 770B |
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <iterator>
using namespace std;
char a[26] = {"2223334445556667777888999"};
int main() {
map<string, int> m;
map<string, int >::iterator iter;
string s,t;
int n,i,len;
bool dup = false;
for(scanf("%d",&n); n--;)
{
cin >> s;
len = s.length();
for (int i = 0; i < len; ++i)
{
if(s[i] <= 'Z' && s[i] >= 'A') t.push_back(a[s[i] - 'A']);
else{if(s[i] != '-') t.push_back(s[i]);}
}
t.insert(3, 1, '-');
m[t] ++;
t.clear();
}
for(iter = m.begin(); iter != m.end(); ++iter)
{
if(iter->second > 1)
{
dup = true;
cout << iter->first <<" " << iter->second << endl;
}
}
if (!dup) puts("No duplicates.");
return 0;
}
就是把do while改成for循环,并把输入放到for中,代码就少了300多B。我发现同样的代码poj每次测的数据略有不同,但是如果没有什么真正改进,比如去掉{},空格什么的,好像并没什么作用。
=====================================
如果把map换成数组,不用stl应该快不少,看下边的代码,我对中间的判断做了一点优化,转自:http://www.wutianqi.com/?p=308
1002 Accepted 2120K 625MS C++ 1257B
#include <iostream>
using namespace std;
char hash[] = "22233344455566670778889990";
char telphone[100001][20];
char temp[20];
int compare( const void *arg1, const void *arg2 )
{
return strcmp((char*)arg1, (char*)arg2 );
}
int main()
{
int flag = 0, nCases;
scanf("%d", &nCases);
for(int i = 0; i < nCases; ++i)
{
getchar();
scanf("%s", telphone[i]);
int len = strlen(telphone[i]);
int t = 0;
for(int j = 0; j < len; ++j)
{
if(telphone[i][j] >= 'A' && telphone[i][j] <= 'Z')
temp[t++] = hash[telphone[i][j]-'A'];
else {if(telphone[i][j] != '-') temp[t++] = telphone[i][j];}
}
strcpy(telphone[i], temp);
}
qsort(telphone, nCases, sizeof(telphone[0]), compare);
for(int i = 0; i < nCases; ++i)
{
int cnt = 1;
strcpy(temp, telphone[i]);
int j;
for(j = i+1; j < nCases; ++j)
{
if(strcmp(temp, telphone[j]) == 0)
cnt++;
else
break;
}
if(cnt > 1) //这个地方没处理好,麻烦。。。
{
flag = 1;
for(int k = 0; k < 3; ++k)
printf("%c", temp[k]);
printf("-");
for(int k = 3; k < 7; ++k)
printf("%c", temp[k]);
printf(" %d\n", cnt);
}
i = j-1;
}
if(flag == 0)
printf("No duplicates.\n");
return 0;
}