P2037 电话号码
题目描述
一串由长长的数字组成的电话号码通常很难记忆。为了方便记忆,有种方法是用单词来方便记忆。例如用“Three Tens”来记忆电话3-10-10-10。
电话号码的标准形式是七位数字,中间用连字号分成前三个和后四个数字(例如: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。
如果两个电话号码的标准形式是一样的,那么这两个电话号码就是一样的。
现在有一本电话簿,请从中找出哪些电话号码是重复的。
输入输出格式
输入格式:
第一行一个正整数N,表示有多少个电话号码。
以下N行,每行一个电话号码,电话号码由数字、大写字母(除Q、Z)和连字符组成。电话号码长度不会超过1000。所有电话号码都合法。
输出格式:
将所有重复的电话号码按字典序以标准形式输出,并且在每个电话号码后跟一个整数,表示该电话号码共出现了多少次,电话号码和整数间用一个空格隔开。不要输出多余空行。
如果没有重复的电话号码,则输出:No duplicates.
输入输出样例
说明
【数据范围】
对于30%的数据,N<=20。
对于50%的数据,N<=10000。
对于100%的数据,N<=100000。
不用开map

/*用一个map把所有的字母表示的数字存起来,0和1题目中没说,但也要表示。 一个<string,int>类型的map表示a这个字符串出现的次数。 把每个读入的字符串转化为标准形式存起来,如果有出现次数超过两次的,存起来,答案数++。 最后将答案按字典序排序输出。 (如果map的初始化写到了函数里,别忘记调用!!!,一开始没调用,全输出的空格,调了半个多小时)。*/ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<map> #include<string> using namespace std; int n,cnt,now,pos,sum[100005]; string s,temp,tot[100005]; map<char,char> excel; map<string,int> a; struct Ans { int cs; string chuan; }ans[100005]; void init() //初始化函数 { excel['0']='0';excel['1']='1'; excel['A']=excel['B']=excel['C']=excel['2']='2'; excel['D']=excel['E']=excel['F']=excel['3']='3'; excel['G']=excel['H']=excel['I']=excel['4']='4'; excel['J']=excel['K']=excel['L']=excel['5']='5'; excel['M']=excel['N']=excel['O']=excel['6']='6'; excel['P']=excel['R']=excel['S']=excel['7']='7'; excel['T']=excel['U']=excel['V']=excel['8']='8'; excel['W']=excel['X']=excel['Y']=excel['9']='9'; } bool cmp(Ans a,Ans b) { return a.chuan+b.chuan<b.chuan+a.chuan; } int main() { init(); //千万千万别忘记调用 scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>s; temp.clear();pos=0; //将temp清空,pos归零 for(int j=0;j<s.length();j++) { if(s[j]!='-') //转化为数字 { temp+=excel[s[j]]; pos++; } if(pos==3) temp+='-',pos=-999999999; //到了该加'-'的地方,加上'-',同时将pos设为负值,防止重复添加 } if(!a[temp]) tot[++cnt]=temp; //如果这个字符串没出现过,将这个字符串加入到已有的字符串中 a[temp]++; //该字符串出现的次数++ } for(int i=1;i<=cnt;i++) //找哪个字符串是重复的 { if(a[tot[i]]>1) { ans[++now].chuan=tot[i]; //存答案 ans[now].cs=a[tot[i]]; } } if(!now) //没有重复的 { printf("No duplicates."); return 0; } sort(ans+1,ans+now+1,cmp); //按字典序排列 for(int i=1;i<=now;i++) { cout<<ans[i].chuan<<' '; printf("%d\n",ans[i].cs); } return 0; }

/*用一个map把所有的字母表示的数字存起来,0和1题目中没说,但也要表示。 一个<string,int>类型的map表示a这个字符串出现的次数。 把每个读入的字符串转化为标准形式存起来,如果有出现次数超过两次的,存起来,答案数++。 最后将答案按字典序排序输出。 (如果map的初始化写到了函数里,别忘记调用!!!,一开始调用,全输出的空格,调了半个多小时)。*/ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<map> #include<string> using namespace std; int n,cnt,now,pos,sum[100005]; string s,temp,tot[100005]; char excel[100]; map<string,int> a; struct Ans { int cs; string chuan; }ans[100005]; void init() //初始化函数 { excel['0']='0';excel['1']='1'; excel['A']=excel['B']=excel['C']=excel['2']='2'; excel['D']=excel['E']=excel['F']=excel['3']='3'; excel['G']=excel['H']=excel['I']=excel['4']='4'; excel['J']=excel['K']=excel['L']=excel['5']='5'; excel['M']=excel['N']=excel['O']=excel['6']='6'; excel['P']=excel['R']=excel['S']=excel['7']='7'; excel['T']=excel['U']=excel['V']=excel['8']='8'; excel['W']=excel['X']=excel['Y']=excel['9']='9'; } bool cmp(Ans a,Ans b) { return a.chuan+b.chuan<b.chuan+a.chuan; } int main() { init(); //千万千万别忘记调用 scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>s; temp.clear();pos=0; //将temp清空,pos归零 for(int j=0;j<s.length();j++) { if(s[j]!='-') //转化为数字 { temp+=excel[s[j]]; pos++; } if(pos==3) temp+='-',pos=-999999999; //到了该加'-'的地方,加上'-',同时将pos设为负值,防止重复添加 } if(!a[temp]) tot[++cnt]=temp; //如果这个字符串没出现过,将这个字符串加入到已有的字符串中 a[temp]++; //该字符串出现的次数++ } for(int i=1;i<=cnt;i++) //找哪个字符串是重复的 { if(a[tot[i]]>1) { ans[++now].chuan=tot[i]; //存答案 ans[now].cs=a[tot[i]]; } } if(!now) //没有重复的 { printf("No duplicates."); return 0; } sort(ans+1,ans+now+1,cmp); //按字典序排列 for(int i=1;i<=now;i++) { cout<<ans[i].chuan<<' '; printf("%d\n",ans[i].cs); } return 0; }