版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/peter_xiazhen/article/details/86562908
好久不打代码了,这道题也是wa了老半天,废话不多说,先说几个坑点吧。
①、POJ的数据范围很大,所以不要用string了,TLE到怀疑人生。
②、统计每个电话号码的出现次数,把至少出现一次的电话号码,按照字典序输出。所以有两个想法。
<1>、直接用数组,数组的下标表示电话号码,存的是出现的次数,好处就是不用排序了,下标的遍历就是
按照字典序,从小到大的。但是,敲黑板,代价就是你必须数组开得很大,1e7保底吧,不然内存爆炸到怀疑人生。
<2>、第二种高级一点,用到的是Map,Map是一种集合容器,能够把Key-Value一一对应起来,试想关键字就表示电话号码,
存的是出现的次数,还有一个好处是Map存储的时候其实是有序的,它会按照关键字的字典序存储,包括输出,很省事了。
但是map在使用的时候,迭代器那里得注意。
③、输出的时候,因为是按照格式输出,所以 printf("%03d-%04d %d\n",i/10000,i%10000,num[i]);
注意注意0不能丢,要对齐的。代码如下
第一种:
#include <stdio.h>
#include <string.h>
const int maxn=1e7+5;
int num[maxn];//这个数组开大一点,因为想用数组下标来表示电话号码
char s[110]; //这里有个好处是不用排序了,下表就是从小到大遍历的
int n;
int converse(char temp) //将字符转换成数字
{
if (temp>='0'&&temp<='9') return temp-'0' ;
else if (temp=='A'||temp=='B'||temp=='C') return 2;
else if (temp=='D'||temp=='E'||temp=='F') return 3;
else if (temp=='G'||temp=='H'||temp=='I') return 4;
else if (temp=='J'||temp=='K'||temp=='L') return 5;
else if (temp=='M'||temp=='N'||temp=='O') return 6;
else if (temp=='P'||temp=='R'||temp=='S') return 7;
else if (temp=='T'||temp=='U'||temp=='V') return 8;
else if (temp=='W'||temp=='X'||temp=='Y') return 9;
else return -1;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
int cnt = strlen(s);
int tol=0;
for(int j=0;j<cnt;j++)
{
int temp = converse(s[j]);
if (temp==-1) continue;
else tol=tol*10+temp;
}
num[tol]++;
}
bool flag = false;
for(int i=0;i<maxn;i++)
{
if (num[i]>1)
{
flag = true;
printf("%03d-%04d %d\n",i/10000,i%10000,num[i]);
}
}
if (!flag) printf("No duplicates.\n");
return 0;
}
第二种
#include <stdio.h>
#include <string>
#include <string.h>
#include <map>
#include <iostream>
using namespace std;
int n;
char s[110];
map<int,int,greater<int> > q; //这里可以修该map的KEY默认排序规则,加上greater<int>
//就变成了从大到小排序
int solve(char temp)
{
if(temp>='0'&&temp<='9') return temp-'0';
else if (temp=='A'||temp=='B'||temp=='C') return 2;
else if (temp=='D'||temp=='E'||temp=='F') return 3;
else if (temp=='G'||temp=='H'||temp=='I') return 4;
else if (temp=='J'||temp=='K'||temp=='L') return 5;
else if (temp=='M'||temp=='N'||temp=='O') return 6;
else if (temp=='P'||temp=='R'||temp=='S') return 7;
else if (temp=='T'||temp=='U'||temp=='V') return 8;
else if (temp=='W'||temp=='X'||temp=='Y') return 9;
else return -1;
}
int main()
{
scanf("%d",&n);
getchar();
for(int i=1;i<=n;i++)
{
scanf("%s",s);
int tol=0;
int cnt=strlen(s);
for(int j=0;j<cnt;j++)
{
int temp = solve(s[j]);
if (temp==-1) continue;
else tol =tol*10+temp;
}
q[tol]++;
}
map<int,int>::iterator iter; //map的专用迭代器,作为遍历map用的
bool flag = false; //map是有序容器,默认是按照key的字典序排序
for(iter =q.begin();iter!=q.end();iter++)
{
if (iter->second>1)
{
flag =true;
printf("%03d-%04d %d\n",iter->first/10000,iter->first%10000,iter->second);
}
}
if (!flag) printf("No duplicates.\n");
return 0;
}