【题目】
企业想拥有令人难忘的电话号码。要一个电话号码让人容易记住,方法之一是号码里面有一个难忘的单词或词组拼写。例如,您可以拨打TUT- GLOP拨打沃特卢大学。有时电话号码只有一部分是单词拼写。当你回到你的酒店,今晚你可以通过拨打310 - GINO吉诺订购比萨饼。另一种方法,设计的电话号码是一个难忘的方式分组数字。你可以通过拨打必胜客" 3个10 "的号码3-10-10-10 来订购比萨.
一个电话号码的标准形式是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 。两个电话号码是等价的,如果它们具有相同的标准形式.(他们拨打同一个号码。 )你的公司正在编制当地企业的电话号码目录。作为质量控制过程的一部分,你要检查,没有两个(或以上)的企业目录中的有相同的电话号码.
输入输入将包括一个案例。输入的第一行中指定的目录中的电话号码的数目(最多10万)作为单独行上的一个正整数.其余各行列出在目录中的电话号码,在单独一行的每个数字。每个电话号码的十进制数字,大写字母(不包括Q和Z )和连字符组成的字符串组成. 整整7个数字或字母的字符串中的字符.
产量
生成一行输出为每个电话号码,任何形式多次出现。该行应得到的标准形式的电话号码,后跟一个空格,其次是在电话号码出现在目录的次数。电话号码升字典顺序排列输出线。如果没有重复在输入打印线:
No duplicates.
【样例输入】
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
【样例输出】
310-1010 2
487-3279 4
888-4567 3
解题思路:
由于这道题的复杂度要求比较高,如果直接用字符串来存放输入的话,就会TLE。
所以最好的办法是用int数组来存放。2^32=4'294'967'296,长度已经超过了7,所以没有问题。
然后我考虑用getline(cin,s)来输入字符串,但是发现会runtime error。所以最后只能采用getchar().
接下来是把字符串转换成对应的数字:
遇到‘-’就跳过。
如果遇到大写字母,应该用所给的定义转换。不难发现Q没了,那么在A-P之间有个规律:(ch-'A')/3+2。
由于Q没了,所以R-Y就相当于往前移了一位,所以规律变为(ch-'A'-1)/3+2。
在字符串全部转为数字串之后,题目要求按字典升序排列,所以可以考虑sort函数排序(或qsort)
#include<iostream>
#include<algorithm>
#include<string>
#include<stdlib.h>
using namespace std;
int main(){
//freopen("in1.txt","r",stdin);
int n;
cin>>n;
int *a = (int *)malloc(sizeof(int) * (n)+10);
//int total=0;
getchar();//吃掉换行符
for(int i=0;i<n;i++){
int temp=0;
char ch=getchar();
while(ch!='\n'){
if(ch!='-'){
//temp=temp*10;
if(ch>='A' && ch<='P'){
temp=temp*10+(ch-'A')/3+2;
}
else if(ch>='R' && ch<='Y'){
temp=temp*10+(ch-'A'-1)/3+2;
}
else if(ch>='0' && ch<='9'){
temp=temp*10+ch-'0';
}
}
ch=getchar();
}
a[i]=temp;
}
sort(a,a+n);
int flag=0;
for(int i=0;i<n-1;i++){
int count=1;
while(i+1<n && a[i]==a[i+1]){
count++;
i++;
}
if(count>1){
flag=1;
printf("%03d-%04d %d\n",a[i] / 10000 ,a[i] % 10000 ,count); //前导0的处理很重要!!
/* if(a[i]>=1000000)
cout<<a[i]/10000<<"-";
else if(100000<=a[i]&& a[i]<=999999)
cout<<"0"<<a[i]/10000<<"-";
else if(10000<=a[i]&& a[i]<=99999)
cout<<"00"<<a[i]/10000<<"-";
else
cout<<"000"<<"-";
if(1000<=(a[i]%10000)&&(a[i]%10000)<=9999)
cout<<a[i]%10000;
else if(100<=(a[i]%10000)&&(a[i]%10000)<=999)
cout<<"0"<<"-"<<a[i]%10000;
else if(10<=(a[i]%10000)&&(a[i]%10000)<=99)
cout<<"00"<<"-"<<a[i]%10000;
else if(0<=(a[i]%10000)&&(a[i]%10000)<=9)
cout<<"000"<<a[i]%10000;
cout<<" "<<count<<endl;
*/
}
}
if(flag==0)
cout<<"No duplicates."<<endl;
getchar();
return 0;
}