我现在真想抓狂.今天就光做这个题目了,怎么弄都是超时,郁闷死了.把以前做的题目一看,用了一个map就不超时,太郁闷了.题目是这样的:
企业喜欢用容易被记住的电话号码。让电话号码容易被记住的一个办法是将它写成一个容易记住的单词或者短语。例如,你需要给滑铁卢大学打电话时,可以拨打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。
如果两个号码有相同的标准格式,那么他们就是等同的(相同的拨号)
你的公司正在为本地的公司编写一个电话号码薄。作为质量控制的一部分,你想要检查是否有两个和多个公司拥有相同的电话号码。
Input
输入的格式是,第一行是一个正整数,指定电话号码薄中号码的数量(最多100000)。余下的每行是一个电话号码。每个电话号码由数字,大写字母(除了Q和Z)以及连接符组成。每个电话号码中只会刚好有7个数字或者字母。
Output
对于每个出现重复的号码产生一行输出,输出是号码的标准格式紧跟一个空格然后是它的重复次数。如果存在多个重复的号码,则按照号码的字典升序输出。如果输入数据中没有重复的号码,输出一行:
No duplicates.
Sample Input
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
Sample Output
310-1010 2
487-3279 4
888-4567 3
然后今天做题,我就想到用vector,可是,用vector后就得自己排序,我用到的排序是快排,但是提交以后老是说超时,很是郁闷.
程序大致为两个部分,前面一部分是将对应弄成数字存在vector,另一部分就是快排.
代码一:
1 #include <iostream>
2 #include <vector>
3 #include <string>
4 #include <stdlib.h>
5 using namespace std;
6
7 vector<string> QuickSort(vector<string> m,int low,int high,int* a)//快排
8 {
9 int i=low,j=high;
10 string tem=m[low];
11 int atem=a[low];
12 while(i<j)
13 {
14 while(i<j&&tem<=m[j])j--;
15 if(i<j)
16 {
17 m[i]=m[j];
18 a[i]=a[j];
19 i++;
20 }
21 while(i<j&&m[i]<tem)i++;
22 if(i<j)
23 {
24 m[j]=m[i];
25 a[j]=a[i];
26 j--;
27 }
28 }
29 m[i]=tem;
30 a[i]=atem;
31 if(low<i)QuickSort(m,low,i-1,a);
32 if(i<high)QuickSort(m,j+1,high,a);
33 return m;
34
35 }
36 int main()
37 {
38 vector<string> m_putin;
39 vector<string> m_restore;
40 int n;
41 int* a;
42 string m_one;
43 bool m_has = false;
44 while (cin >> n)
45 {
46 int i=0;
47 a=new int[n];
48 while ( n-- && ( cin>>m_one ))
49 {
50 a[i]=1;
51 i++;
52 m_restore.push_back(m_one);
53 }
54
55 for(vector<string>::size_type cx=0;cx!=m_restore.size();++cx)
56 {
57 m_one=m_restore[cx];
58 string m_tem;
59 for ( string::size_type index = 0;index != m_one.size();++index)
60 {//下面是将字母和数字对应起来.
61 if ( m_one[index] == '-' ) continue;
62 if ( m_one[index]>='0'&&m_one[index]<='9' )
63 { m_tem = m_tem + m_one[index];
64 }
65 else if ( m_one[index] <= 'O')
66 {
67 int m_tem2=(int)(m_one[index]-'A');
68 m_tem2=m_tem2/3+2;
69 char m_tem3[2];
70 _itoa(m_tem2,m_tem3,10);
71 m_tem=m_tem+m_tem3;
72 }
73 else if( m_one[index]>='T')
74 {
75 int m_tem2=(int)(m_one[index]-60);
76 m_tem2=m_tem2/3;
77 char m_tem3[2];
78 _itoa(m_tem2,m_tem3,10);
79 m_tem=m_tem+m_tem3;
80 }
81 else
82 {
83 m_tem=m_tem+"7";
84 }
85 }
86 vector<string>::size_type ax;
87 for ( ax=0;ax != m_putin.size();++ax)
88 {
89 if ( m_putin[ax] == m_tem )
90 {
91 a[ax]++;
92 m_has = true;
93 break;
94 }
95 }
96 if ( ax == m_putin.size() )
97 {
98 m_putin.push_back( m_tem );
99 }
100 }
101 if ( !m_has )
102 {
103 cout << "No duplicates." << endl;
104 }
105 else
106 {
107 m_restore.clear();
108 vector<string>::size_type ax,bx;
109 string m;
110 int mm;
111 for ( ax=0,bx=0;ax != m_putin.size();++ax)
112 {
113 if(a[ax]!=1)
114 {
115 m_restore.push_back(m_putin[ax]);
116 a[bx]=a[ax];
117 bx++;
118 }
119
120 }
121 if(m_restore.size()!=1)
122 m_restore=QuickSort(m_restore,0,m_restore.size()-1,a);//排序部分
123 for ( ax=0;ax != m_restore.size();++ax)//输出
124 {
125 if ( a[ax] == 1 ) continue;
126 m_one=m_restore[ax];
127 for(bx=0;bx!=m_one.size();++bx)
128 {
129 if(bx==3)cout<<"-";
130 cout<<m_one[bx];
131 }
132 cout<<" "<<a[ax]<<endl;
133
134 }
135 }
136 delete a;
137 m_has=false;
138 m_putin.clear();
139 m_restore.clear();
140 }
141 return 0;
142 }
上面这份代码就是提交之后老是超时,我很是受不了,就换成map来做这个题目.不够也说明排序不行,得补补.
下面是用map做的代码二:
1 #include <iostream>
2 #include <map>
3 #include <string>
4 #include <stdlib.h>
5 using namespace std;
6
7 int main()
8 {
9 int n;
10 map<string,int> m;//map
11 string m_one;
12 bool m_has=false;//用来判断是否有重复出现.
13 while(cin>>n)//输入有多少号码
14 {
15 m_has=false;
16 while(n-- && cin>>m_one)//输入每一个号码,对每一个号码进行处理.
17 {
18 string m_tem;
19 for(string::size_type index=0;index!=m_one.size();++index)//对号码进行对应
20 {
21 if ( m_one[index] == '-' ) continue;
22 else if ( m_one[index]=='A'||m_one[index]=='B'||m_one[index]=='C')m_tem=m_tem+'2';
23 else if ( m_one[index]=='D'||m_one[index]=='E'||m_one[index]=='F')m_tem=m_tem+'3';
24 else if ( m_one[index]=='G'||m_one[index]=='H'||m_one[index]=='I')m_tem=m_tem+'4';
25 else if ( m_one[index]=='J'||m_one[index]=='K'||m_one[index]=='L')m_tem=m_tem+'5';
26 else if ( m_one[index]=='M'||m_one[index]=='N'||m_one[index]=='O')m_tem=m_tem+'6';
27 else if ( m_one[index]=='P'||m_one[index]=='R'||m_one[index]=='S')m_tem=m_tem+'7';
28 else if ( m_one[index]=='T'||m_one[index]=='U'||m_one[index]=='V')m_tem=m_tem+'8';
29 else if ( m_one[index]=='W'||m_one[index]=='X'||m_one[index]=='Y')m_tem=m_tem+'9';
30 else if ( m_one[index]>='0'&&m_one[index]<='9')m_tem=m_tem+m_one[index];
31 }
32 m[m_tem]++;//加入map里面
33 }
34 for(map<string,int>::iterator it=m.begin();it!=m.end();++it)//输出号码
35 {
36 if(it->second>1)//判断是否有重复
37 {
38 m_one=it->first;//如果有,则得到字符串
39 for(string::size_type ax=0;ax!=m_one.size();++ax)//加'-'
40 {
41 if(ax==3)
42 cout<<"-";
43 cout<<m_one[ax];
44 }
45 cout<<" "<<it->second<<endl;
46 m_has=true;
47 }
48 }
49 if(!m_has)cout<<"No duplicates."<<endl;//没有重复
50 m.clear();//必须有这个
51 }
52 return 0;
53 }
这个是用string作为关键字,int是它的重复次数.因为map本身就是有序的,所以就不用排,但是如果数据量很大很大的话,map是不是就装不下了呢,那样的话,是不是就必须用排序的算法,那还是转到代码一解决,以后有机会想想如何让它利用排序的情况下不用超时.记下来了.
另外一个就是用int作为关键字,将string转成整形型.在写代码二的时候已经是晚上回到寝室了,有点急了,所以自己就没有考虑49行的代码,然后就提交上去,提交了好多次,老是Wrong ,就改对应转换的那部分,弄成下面的代码一里面的那部分.但是还是错的.还是又看了以前写的,才恍然大悟,哦,自己还有没有输出的.以后要静下心来,一定要静下心来,不要老想着提交正确,更多的是学到知识,像今天,虽然代码提交了,但是这两个用的vector,map还是不清楚,就应该静下心来把相关知识看懂,记下来,才能越做越好,要不然以后还是什么都不会.明天看vector,map,记住了.java代码写的明天弄.