二零一七一月二十一日小测试

problem A:点击打开链接内网点击打开链接外网

题目大意

企业喜欢用容易被记住的电话号码。让电话号码容易被记住的一个办法是将它写成一个

容易记住的单词或者短语。例如,你需要给滑铁卢大学打电话时,可以拨打 TUT-GLOP。有
时,只将电话号码中部分数字拼写成单词。当你晚上回到酒店,可以通过拨打 310-GINO 来
向 Gino's 订一份 pizza。让电话号码容易被记住的另一个办法是以一种好记的方式对号码
的数字进行分组。通过拨打必胜客的“三个十”号码3-10-10-10,你可以从他们那里订
pizza。  
电话号码的标准格式是七位十进制数,并在第三、第四位数字之间有一个连接符。电话
拨号盘提供了从字母到数字的映射,映射关系如下:  
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。  
如果两个号码有相同的标准格式,那么他们就是等同的(相同的拨号)  
你的公司正在为本地的公司编写一个电话号码薄。作为质量控制的一部分,你想要检查
是否有两个和多个公司拥有相同的电话号码。  
 
【输入格式】 
输入的格式是,第一行是一个正整数,指定电话号码薄中号码的数量(最多 100000)。
余下的每行是一个电话号码(长度不超过 15)。每个电话号码由数字,大写字母(除了 Q
和 Z)以及连接符组成。每个电话号码中只会刚好有7 个数字或者字母。 

【输出格式】 
对于每个出现重复的号码产生一行输出,输出是号码的标准格式紧跟一个空格然后是它
的重复次数。如果存在多个重复的号码,则按照号码的字典升序输出。如果输入数据中没有
重复的号码,输出一行“ No duplicates. ”。 
 【数据范围】 
  对于30% 的数据,0<N<=500; 
  对于60% 的数据,0<N<=10000; 
  对于100% 的数据,0<N<=100000。 
  
【输出样例 1】telephone.out 
310-1010 2 
487-3279 4 
888-4567 3 
 
 
【输入样例 2】telephone.in 

4875279 
ITS-EASY 
TUT-GLOP 
310-GINO 
F101010 
888-1200 
 
【输出样例 2】telephone.out 
No duplicates. 
 
 

第一眼就发现这道题的数据小,于是就考虑使用类哈希的思想-----先将每个数据转化为数字,再将对应数字的标志++。(因为只有7位数,而且n比较小,所以因该不会爆)

后来不放心,做了一个小优化,在转换的时候记录下了数据中的最小值和最大值,要不然要从1000000扫描到9999999。。。

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
using namespace std;
char s[20];
int bz[10000009],n,a[100010],maxn=0,minn=1E+10;
void zhuanhuan(int o)
{
int l=strlen(s+1),x=0;
for(int i=1;i<=l;i++)
{
if(s[i]!='-')
{
if(s[i]>='0'&&s[i]<='9')
x=10*x+s[i]-'0';
else
{
if(s[i]>='A'&&s[i]<='C')
x=10*x+2;
if(s[i]>='D'&&s[i]<='F')
x=10*x+3;
if(s[i]>='G'&&s[i]<='I')
x=10*x+4;
if(s[i]>='J'&&s[i]<='L')
x=10*x+5;
if(s[i]>='M'&&s[i]<='O')
x=10*x+6;
if(s[i]=='P'||s[i]=='S'||s[i]=='R')
x=10*x+7;
if(s[i]>='T'&&s[i]<='V')
x=10*x+8;
if(s[i]>='W'&&s[i]<='Y')
x=10*x+9;
}
}
}
a[o]=x;
maxn=max(maxn,x);
minn=min(minn,x);
}
int main()
{
freopen("telephone.in","r",stdin);
freopen("telephone.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
zhuanhuan(i);
}
for(int i=1;i<=n;i++)
bz[a[i]]++;
int check=0;
for(int i=minn;i<=maxn;i++)
if(bz[i]>=2)
{
check=1;
cout<<i/10000;
cout<<"-";
int p=i/10000;
p=p*10000;
cout<<i-p<<" "<<bz[i]<<endl;
}
if(check==0)cout<<"No duplicates.";
return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值