18.4.20 STL专项练习8选6

A:List

描述

写一个程序完成以下命令:
new id ——新建一个指定编号为id的序列(id<10000)
add id num——向编号为id的序列加入整数num
merge id1 id2——合并序列id1和id2中的数,并将id2清空
unique id——去掉序列id中重复的元素
out id ——从小到大输出编号为id的序列中的元素,以空格隔开

输入第一行一个数n,表示有多少个命令( n<=200000)。以后n行每行一个命令。输出按题目要求输出。样例输入

16
new 1
new 2
add 1 1
add 1 2
add 1 3
add 2 1
add 2 2
add 2 3
add 2 4
out 1
out 2
merge 1 2
out 1
out 2
unique 1
out 1

样例输出

1 2 3 
1 2 3 4
1 1 2 2 3 3 4

1 2 3 4
 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <iterator>
 4 #include <list>
 5 #include <algorithm>
 6 #include <string>
 7 
 8 using namespace std;
 9 list<int> all[10005];
10 
11 int main()
12 {
13     int n;
14     cin >> n;
15     for (int i = 1; i <= n; i++) {
16         string line;
17         cin >> line;
18         if (line == "new") {
19             int id;
20             cin >> id;
21         }
22         if (line == "add") {
23             int id, num;
24             cin >> id >> num;
25             all[id].push_back(num);
26             all[id].sort();
27         }
28         if (line == "out") {
29             int id;
30             cin >> id;
31             list<int>::iterator p;
32             p = all[id].begin();
33             if (p != all[id].end())
34             {
35                 cout << *p++;
36                 for (; p != all[id].end(); p++)
37                     cout << " " << *p;
38             }
39             cout << endl;
40         }
41         if (line == "merge") {
42             int a, b;
43             cin >> a >> b;
44             all[a].merge(all[b]);
45             all[a].sort();
46         }
47         if (line == "unique") {
48             int id;
49             cin >> id;
50             all[id].unique();
51         }
52     }
53             return 0;
54 }
View Code

太暴力了,不要效仿

B:RPN Calculator

描述

Reverse Polish notation (or just RPN) by analogy with the related Polish notation, a prefix notation introduced in 1920 by the Polish mathematician Jan Łukasiewicz, is a mathematical notation wherein every operator follows all of its operands. It is also known as Postfix notation.

In Reverse Polish notation the operators follow their operands; for instance, to add three and four one would write "3 4 +" rather than "3 + 4". If there are multiple operations, the operator is given immediately after its second operand; so the expression written "3 − 4 + 5" in conventional infix notation would be written "3 4 − 5 +" in RPN: first subtract 4 from 3, then add 5 to that. An advantage of RPN is that it obviates the need for parentheses that are required by infix. While "3 − 4 * 5" can also be written "3 − (4 * 5)", that means something quite different from "(3 − 4) * 5", and only the parentheses disambiguate the two meanings. In postfix, the former would be written "3 4 5 * −", which unambiguously means "3 (4 5 *) −".

You were asked to design a simple RPN calculator, which will support the “+”, “-“, “*”, “/”(the absolute value of the divisor will not less then 10^-9) and “^”(power operator, if the base number b<=0, the exponential e must be a positive integer not greater than 10^9) operators. You can assume all the numbers during the calculation can fit into a double-precision floating point number.

In addition, our calculator has some memory. Each time we calculate an expression, the smallest number in the memory will be erased, and replace it with the value of the expression.

输入

The first line contains an integer n, which is the memory size of our calculator.

 

From the second line, we will give n numbers, which is the initial value of the memory. each line except last will have 10 numbers.


And then each line has a valid RPN expression we previously described, end with “=”, which is the command for calculation. Each term will no longer than 20 characters.

输出For each expression, output the value of it in a line.
And then output an empty line to separate the two parts.
At last, output the all the numbers in memory, in increasing order, 10 numbers per line.

Each number should be formatted in scientific notation with 6 digits after decimal point and 2 digits of exponential, such like “%e” format string of printf() function in C. The numbers in a line should be separated by a space.样例输入

4
1e6 1e-6 0.001 1000
1 2 + 3 4 + * =
1 0.1 / 8 ^ =

样例输出

2.100000e+01
1.000000e+08

2.100000e+01 1.000000e+03 1.000000e+06 1.000000e+08

提示

Huge input, scanf() is recommended

%e格式输出在windows环境下指数部分为3位,在系统的测试环境下为2位。

 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <iterator>
 4 #include <list>
 5 #include <stack>
 6 #include <algorithm>
 7 #include <string>
 8 #include <set>
 9 #include <math.h>
10 
11 using namespace std;
12 
13 int main()
14 {
15     stack<double> memory;
16     multiset<double> res;
17     int n;
18     cin >> n;
19     for (int i = 1; i <= n; i++) {
20         double num;
21         scanf("%lf", &num);
22         res.insert(num);
23     }
24     string sign;
25     while (cin >> sign) {
26             if (sign == "=") {
27                 double s = memory.top();
28                 printf("%e\n", s);
29                 memory.pop();
30                 multiset<double> ::iterator h=res.begin();
31                 res.erase(h);
32                 res.insert(s);
33             }
34             else if(sign == "+" || sign == "-" || sign == "*" || sign == "/" || sign == "^")
35             {
36                 double num1, num2,re;
37                 num1 = memory.top();
38                 memory.pop();
39                 num2 = memory.top();
40                 memory.pop();
41                 if (sign == "+")
42                     re=num1 + num2;
43                 else if (sign == "-")
44                     re=num2 - num1;
45                 else if (sign == "*")
46                     re=num2*num1;
47                 else if (sign == "/")
48                     re=num2 / num1;
49                 else if (sign == "^")
50                     re=pow(num2, num1);
51                 memory.push(re);
52             }
53             else {
54                 double num;
55                 num = atof(sign.c_str());
56                 memory.push(num);
57             }
58         }
59     cout << endl;
60     multiset<double>::iterator i=res.begin();
61     int count = 0;
62     for (; i != res.end(); i++) {
63         count++;
64         if(count%10==0)
65             printf("%e\n", *i);
66         else
67             printf("%e ", *i);
68     }
69     cout << endl;
70     return 0;
71 }
View Code

英文没耐心读题意理解错了很多次

一直RE的原因居然是循环中sign几种情况的顺序问题

未解之谜

有同学说是因为有负数数据 非常有道理(5.13update)

C:Set

描述现有一整数集(允许有重复元素),初始为空。我们定义如下操作:
add x 把x加入集合
del x 把集合中所有与x相等的元素删除
ask x 对集合中元素x的情况询问
对每种操作,我们要求进行如下输出。
add 输出操作后集合中x的个数
del 输出操作前集合中x的个数
ask 先输出0或1表示x是否曾被加入集合(0表示不曾加入),再输出当前集合中x的个数,中间用空格格开。输入第一行是一个整数n,表示命令数。0<=n<=100000。
后面n行命令,如Description中所述。输出共n行,每行按要求输出。样例输入

7
add 1
add 1
ask 1
ask 2
del 2
del 1
ask 1

样例输出

1
2
1 2
0 0
0
2
1 0

提示

Please use STL’s set and multiset to finish the task

 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <iterator>
 4 #include <list>
 5 #include <stack>
 6 #include <algorithm>
 7 #include <string>
 8 #include <set>
 9 
10 using namespace std;
11 
12 int main()
13 {
14     multiset<int> all;
15     set<int> record;
16     int n;
17     cin >> n;
18     for (int i = 1; i <= n; i++) {
19         string line;
20         cin >> line;
21         if (line == "add") {
22             int num;
23             cin >> num;
24             all.insert(num);
25             record.insert(num);
26             cout << all.count(num)<<endl;
27         }
28         if (line == "del") {
29             int num;
30             cin >> num;
31             int c = all.count(num);
32             cout << c<< endl;
33             if (c) {
34                 int count = 0;
35                 for (;; ) {
36                     all.erase(all.lower_bound(num));
37                     count++;
38                     if (count == c)break;
39                 }
40             }
41         }
42         if (line == "ask") {
43             int num; cin >> num;
44             if (record.find(num)==record.end())
45                 printf("0 0\n");
46             else {
47                 cout << "1 " << all.count(num) << endl;
48             }
49         }
50     }
51     return 0;
52 }
View Code

注意题意是ask命令首先输出是否曾加入过

D:字符串操作

描述

给定n个字符串(从1开始编号),每个字符串中的字符位置从0开始编号,长度为1-500,现有如下若干操作:

  • copy N X L:取出第N个字符串第X个字符开始的长度为L的字符串。
  • add S1 S2:判断S1,S2是否为0-99999之间的整数,若是则将其转化为整数做加法,若不是,则作字符串加法,返回的值为一字符串。
  • find S N:在第N个字符串中从左开始找寻S字符串,返回其第一次出现的位置,若没有找到,返回字符串的长度。
  • rfind S N:在第N个字符串中从右开始找寻S字符串,返回其第一次出现的位置,若没有找到,返回字符串的长度。
  • insert S N X:在第N个字符串的第X个字符位置中插入S字符串。
  • reset S N:将第N个字符串变为S。
  • print N:打印输出第N个字符串。
  • printall:打印输出所有字符串。
  • over:结束操作。

其中N,X,L可由find与rfind操作表达式构成,S,S1,S2可由copy与add操作表达式构成。

输入

第一行为一个整数n(n在1-20之间)

 

接下来n行为n个字符串,字符串不包含空格及操作命令等。

 

接下来若干行为一系列操作,直到over结束。

输出

根据操作提示输出对应字符串。

样例输入

3
329strjvc
Opadfk48
Ifjoqwoqejr
insert copy 1 find 2 1 2 2 2
print 2
reset add copy 1 find 3 1 3 copy 2 find 2 2 2 3
print 3
insert a 3 2
printall
over

样例输出

Op29adfk48
358
329strjvc
Op29adfk48
35a8

提示

推荐使用string类中的相关操作函数。

使尽了各种数据还是wa……为啥?!贴个错误代码……我相信我会补上它的……

可能需要重写了mmp

正确代码:

  1 #include <cstdlib>
  2 #include <iostream>
  3 #include <iterator>
  4 #include <list>
  5 #include <stack>
  6 #include <algorithm>
  7 #include <string>
  8 #include <set>
  9 
 10 using namespace std;
 11 
 12 int main()
 13 {
 14     int n;
 15     cin >> n;
 16     string strs[25];
 17     for (int i = 1; i <= n; i++)cin >> strs[i];
 18     string line;
 19     stack<string> order;
 20     while (1) {
 21         getline(cin, line);
 22         if (line == "over")break;
 23         while (1)
 24         {
 25             string tmp;
 26             int end = line.rfind(" ");
 27             if (end == std::string::npos) {
 28                 tmp = line;
 29                 line = "";
 30             }
 31             else {
 32                 tmp = line.substr(end + 1, line.length() - 1);
 33                 line.erase(end, line.length() - 1);
 34             }
 35             if (tmp == "copy") {
 36                 int N, X, L;
 37                 N = atoi(order.top().c_str()); order.pop();
 38                 X = atoi(order.top().c_str()); order.pop();
 39                 L = atoi(order.top().c_str()); order.pop();
 40                 tmp = strs[N].substr(X, L);
 41                 order.push(tmp);
 42             }
 43             else if (tmp == "add") {
 44                 string s1, s2;
 45                 s1 = order.top(); order.pop();
 46                 s2 = order.top(); order.pop();
 47                 if(s1.length()>5||s1.length()>5) order.push(s1 + s2);
 48                 else
 49                 {
 50                 int pt1=1,pt2=1;
 51                 for (unsigned int i = 0; i < s1.length(); ++i)
 52                    if (s1[i] > 57 || s1[i] < 48) {
 53                        pt1 = 0; break;
 54                    }
 55                 for (unsigned int i = 0; i < s2.length(); ++i)
 56                     if (s2[i] > 57 || s2[i] < 48) {
 57                       pt2 = 0; break;
 58                     }
 59                 if(pt1&&pt2){
 60                 int n1, n2;
 61                 n1 = atoi(s1.c_str()), n2 = atoi(s2.c_str());
 62                 order.push(to_string(n1 + n2));}
 63                 else
 64                     order.push(s1 + s2);
 65                 }
 66             }
 67             else if (tmp == "find") {
 68                 string s1, s2;
 69                 s1 = order.top(); order.pop();
 70                 s2 = order.top(); order.pop();
 71                 string S;
 72                 int N;
 73                 S = s1; N = atoi(s2.c_str());
 74                 string oer;
 75                 if (strs[N].find(S) != std::string::npos)
 76                     oer = to_string(strs[N].find(S));
 77                 else
 78                     oer = to_string(strs[N].length());
 79                 order.push(oer);
 80             }//
 81             else if (tmp == "rfind") {
 82                 string s1, s2;
 83                 s1 = order.top(); order.pop();
 84                 s2 = order.top(); order.pop();
 85                 string S;
 86                 int N;
 87                 S = s1; N = atoi(s2.c_str());
 88                 string oer;
 89                 if (strs[N].rfind(S) != std::string::npos)
 90                     oer = to_string(strs[N].rfind(S));
 91                 else
 92                     oer = to_string(strs[N].length());
 93                 order.push(oer);
 94             }
 95             else if (tmp == "insert") {
 96                 string S;
 97                 int N, X;
 98                 S = order.top(); order.pop();
 99                 N = atoi(order.top().c_str()); order.pop();
100                 X = atoi(order.top().c_str()); order.pop();
101                 strs[N].insert(X, S);
102             }
103             else if (tmp == "reset") {
104                 string S = order.top(); order.pop();
105                 int N = atoi(order.top().c_str()); order.pop();
106                 strs[N] = S;
107             }
108             else if (tmp == "print") {
109                 int N = atoi(order.top().c_str()); order.pop();
110                 cout << strs[N] << endl;
111             }
112             else if (tmp == "printall") {
113                 for (int i = 1; i <= n; i++)
114                     cout << strs[i] << endl;
115             }
116             else
117                 order.push(tmp);
118             if (line.length() == 0)break;
119         }
120     }
121     return 0;
122 }
View Code

 

WA原因:atoi()会把890b转化为890

 

E:热血格斗场

描述

为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家热血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。

我们假设格斗的实力可以用一个正整数表示,成为实力值。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有两个人的实力值与他差别相同,则他会选择比他弱的那个(显然,虐人必被虐好)。

不幸的是,Facer一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮facer恢复比赛纪录,按照时间顺序依次输出每场比赛双方的id。

输入

第一行一个数n(0 < n <=100000),表示格斗场新来的会员数(不包括facer)。以后n行每一行两个数,按照入会的时间给出会员的id和实力值。一开始,facer就算是会员,id为1,实力值1000000000。输入保证两人的实力值不同。

输出

N行,每行两个数,为每场比赛双方的id,新手的id写在前面。

样例输入

3
2 1
3 3
4 2

样例输出

2 1
3 2
4 2
 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <iterator>
 4 #include <list>
 5 #include <stack>
 6 #include <algorithm>
 7 #include <string>
 8 #include <set>
 9 #include <map>
10 
11 using namespace std;
12 
13 int main()
14 {
15     multimap<int, int> member;
16     multimap<int, int>::iterator i,j;
17     int n;
18     cin >> n;
19     member.insert(pair<int,int>(1000000000, 1));
20     for (int k = 1; k <= n; k++) {
21         int id, power,adver=1;
22         int min = 1000000000;
23         scanf("%d%d", &id, &power);
24         i = member.lower_bound(power);
25         j = member.upper_bound(power);
26         if (i == j) {
27             if (i != member.begin())
28             {
29                 i--;
30                 adver = i->second;
31                 min = power - i->first;
32                 if (min > j->first - power) {
33                     adver = j->second;
34                     min = power - j->first;
35                 }
36             }
37             else if (i == member.begin()) {
38                 adver = j->second;
39                 min = power - j->first;
40             }
41         }
42         else if (i != j)adver = i->second;
43         printf("%d %d\n", id, adver);
44         member.insert(pair<int, int>(power, id));
45     }
46     return 0;
47 }
View Code

第一次知道cin和cout与c风格输入输出相差那么大……差了几百毫秒

F:冷血格斗场

描述

为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家冷血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。

我们假设格斗的实力可以用一个正整数表示,成为实力值,两人的实力值可以相同。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有多个人的实力值与他差别相同,则他会选择id最小的那个。

不幸的是,Facer一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮facer恢复比赛纪录,按照时间顺序依次输出每场比赛双方的id。

输入

第一行一个数n(0 < n <=100000),表示格斗场新来的会员数(不包括facer)。以后n行每一行两个数,按照入会的时间给出会员的id和实力值。一开始,facer就算是会员,id为1,实力值1000000000。

输出

N行,每行两个数,为每场比赛双方的id,新手的id写在前面。

样例输入

3
2 3
3 1
4 2

样例输出

2 1
3 2
4 2
 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <iterator>
 4 #include <list>
 5 #include <stack>
 6 #include <algorithm>
 7 #include <string>
 8 #include <set>
 9 #include <map>
10 
11 using namespace std;
12 
13 class a {
14 public:
15     int power;
16     int id;
17     a(int m,int n):power(m),id(n){}
18 };
19 class cmp {
20 public:
21     bool operator()(const a&m,const a&n)const {
22         return(m.power < n.power || (m.power == n.power&&m.id < n.id));
23     }
24 };
25 
26 int main()
27 {
28     multimap<a, int,cmp> member;
29     multimap<a, int>::iterator i, j;
30     int n;
31     cin >> n;
32     a tmp(1000000000, 1);
33     member.insert(pair<a, int>(tmp,0));
34     for (int k = 1; k <= n; k++) {
35         int id, power, adver = 1,adverp;
36         int min = 1000000000;
37         scanf("%d%d", &id, &power);
38         tmp.id = id; tmp.power = power;
39         i = member.lower_bound(tmp);
40         j = member.upper_bound(tmp);
41         if (i == j) {
42             if (i != member.begin())
43             {
44                 i--;
45                 adverp = i->first.power;
46                 min = abs(power - adverp);
47                 while (i->first.power == adverp) {
48                     adver = i->first.id;
49                     if (i == member.begin())break;
50                     i--;
51                 }
52                 if (min > j->first.power - power||(min== j->first.power - power&&j->first.id<adver))
53                     adver = j->first.id;
54             }
55             else if (i == member.begin()) 
56                 adver = j->first.id;
57         }
58         else if (i != j) {
59             adverp = i->first.power;
60             while (i->first.power == adverp) {
61                 adver = i->first.id;
62                 if (i == member.begin())break;
63                 i--;
64             }
65         }
66         printf("%d %d\n", id, adver);
67         member.insert(pair<a, int>(tmp, id));
68     }
69     return 0;
70 }
View Code

暴力当然是不行的

但我这种方法总觉得也不太对

G:priority queue练习题

描述

我们定义一个正整数a比正整数b优先的含义是:
*a的质因数数目(不包括自身)比b的质因数数目多;
*当两者质因数数目相等时,数值较大者优先级高。

 

现在给定一个容器,初始元素数目为0,之后每次往里面添加10个元素,每次添加之后,要求输出优先级最高与最低的元素,并把该两元素从容器中删除。

输入

第一行: num (添加元素次数,num <= 30)

下面10*num行,每行一个正整数n(n < 10000000).

输出

每次输入10个整数后,输出容器中优先级最高与最低的元素,两者用空格间隔。

样例输入

1
10 7 66 4 5 30 91 100 8 9

样例输出

66 5
 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <iterator>
 4 #include <list>
 5 #include <stack>
 6 #include <algorithm>
 7 #include <string>
 8 #include <set>
 9 #include <map>
10 #include <queue>
11 #include <math.h>
12 
13 using namespace std;
14 
15 class node {
16 public:
17     int factor, num;
18     node(int x, int y) :num(x), factor(y) {  }
19 };
20 class cmp {
21 public:
22     bool operator()(node a, node b) {
23         return (a.factor < b.factor || (a.factor == b.factor&&a.num < b.num));
24     }
25 };
26 
27 bool judge(int num) {
28     for(int i=2;i<=sqrt(num);i++)
29         if (num%i == 0) return false; 
30     return true;
31 }
32 
33 int factorcal(int num) {
34     int sum=0;
35     for (int i = 2; i <= sqrt(num); i++)
36     {
37         if (num%i == 0) {
38             int k = num / i;
39             if(judge(i))sum++;
40             if (k!=i&&judge(k))sum++;
41         }
42     }
43     return sum;
44 }
45 
46 int main()
47 {
48     set<node, cmp> queue;
49     int n;
50     scanf("%d", &n);
51     for (int loop = 1; loop <= n; loop++) {
52         for (int i = 1; i <= 10; i++) {
53             int num; scanf("%d", &num);
54             node newn(num, factorcal(num));
55             queue.insert(newn);
56         }
57         set<node, cmp>::iterator i = queue.end(); i--;
58         printf("%d %d\n", (*i).num, (*queue.begin()).num);
59         queue.erase(i); i = queue.begin(); queue.erase(i);
60     }
61     return 0;
62 }
View Code

题意误导……自我怀疑了很久

一定要优化循环那里,不然会tle

H:编程填空:数据库内的学生信息

描述

程序填空,使得下面的程序,先输出

(Tom,80),(Tom,70),(Jone,90),(Jack,70),(Alice,100),

(Tom,78),(Tom,78),(Jone,90),(Jack,70),(Alice,100),

(70,Jack),(70,Tom),(80,Tom),(90,Jone),(100,Alice),

(70,Error),(70,Error),(80,Tom),(90,Jone),(100,Alice),

******

然后,再根据输入数据按要求产生输出数据

#include <iostream>
#include <string>
#include <map>
#include <iterator>
#include <algorithm>
using namespace std;
// 在此处补充你的代码
struct Student 
{
    string name;
    int score;
};
template <class T>
void Print(T first,T last) {
    for(;first!= last; ++ first)
        cout << * first << ",";
    cout << endl;
}
int main()
{
    
    Student s[] = { {"Tom",80},{"Jack",70},
                    {"Jone",90},{"Tom",70},{"Alice",100} };
    
    MyMultimap<string,int> mp;
    for(int i = 0; i<5; ++ i)
        mp.insert(make_pair(s[i].name,s[i].score));
    Print(mp.begin(),mp.end()); //按姓名从大到小输出

    mp.Set("Tom",78); //把所有名为"Tom"的学生的成绩都设置为78
    Print(mp.begin(),mp.end());
    
    
    
    MyMultimap<int,string,less<int> > mp2;
    for(int i = 0; i<5; ++ i) 
        mp2.insert(make_pair(s[i].score,s[i].name));
    
    Print(mp2.begin(),mp2.end()); //按成绩从小到大输出
    mp2.Set(70,"Error");          //把所有成绩为70的学生,名字都改为"Error"
    Print(mp2.begin(),mp2.end());
    cout << "******" << endl;
    
    mp.clear();
    
    string name;
    string cmd;
    int score;        
    while(cin >> cmd ) {
        if( cmd == "A") {
            cin >> name >> score;
            if(mp.find(name) != mp.end() ) {
                cout << "erroe" << endl;
            }
            mp.insert(make_pair(name,score));
        }
        else if(cmd == "Q") {
            cin >> name;
            MyMultimap<string,int>::iterator p = mp.find(name);
            if( p!= mp.end()) {
                cout << p->second << endl;
            }
            else {
                cout << "Not Found" << endl; 
            }        
        }
    }
    return 0;
}

输入输入数据的每一行,格式为以下之一:

A name score
Q name score

name是个不带个空格的字符串,长度小于 20
score是个整数,能用int表示

A name score 表示往数据库中新增一个姓名为name的学生,其分数为score。开始时数据库中一个学生也没有。
Q name 表示在数据库中查询姓名为name的学生的分数


数据保证学生不重名。
输入数据少于200,000行。输出对于每个查询,输出学生的分数。如果查不到,则输出 "Not Found"样例输入

A Tom1 30
A Tom2 40
Q Tom3 
A Tom4 89
Q Tom1
Q Tom2

样例输出

(Tom,80),(Tom,70),(Jone,90),(Jack,70),(Alice,100),
(Tom,78),(Tom,78),(Jone,90),(Jack,70),(Alice,100),
(70,Jack),(70,Tom),(80,Tom),(90,Jone),(100,Alice),
(70,Error),(70,Error),(80,Tom),(90,Jone),(100,Alice),
******
Not Found
30
40

提示1) 编写模板的时候,连续的两个 “>”最好要用空格分开,以免被编译器看作是 ">>"运算符。VS可能无此问题,但是Dev C++和服务器上的编译环境会有这个问题。
比如 vector<vector<int>> 有可能出错,要改成 vector<vector<int> >

2) 在模板中写迭代器时,最好在前面加上 typename关键字,否则可能会编译错。VS可能无此问题,但是Dev C++和服务器上的编译环境会有这个问题。

  1 #include <iostream>
  2 #include <string>
  3 #include <map>
  4 #include <iterator>
  5 #include <algorithm>
  6 using namespace std;
  7 template <class key>
  8 class cmp {
  9 public:
 10     bool operator ()(const key&a, const key& b)const {
 11         return a > b;
 12     }
 13 };
 14 template<class key,class value,class pred=cmp<key>>
 15 class MyMultimap
 16 {
 17 public:
 18     typedef multimap<key, value, pred> mmp;
 19     typedef typename multimap<key, value>::iterator iterator;
 20     mmp mp;
 21     iterator insert(pair<key, value> a) {
 22         return mp.insert(a);
 23     }
 24     iterator begin() {
 25         return mp.begin();
 26     }
 27     iterator end() {
 28         return mp.end();
 29     }
 30     void Set(key m, value n) {
 31         pair<iterator, iterator>range = mp.equal_range(m);
 32         iterator i=range.first;
 33         for (; i != range.second; i++) {
 34             i->second = n;
 35         }
 36     }
 37     iterator find(key n) {
 38         return mp.find(n);
 39     }
 40     void clear() {
 41         mp.clear();
 42     }
 43 };
 44 template<class key,class value>
 45 ostream&operator<<(ostream&os, pair<key, value> m) {
 46     os << "(" << m.first << "," << m.second << ")";
 47     return os;
 48 }
 49 struct Student 
 50 {
 51     string name;
 52     int score;
 53 };
 54 template <class T>
 55 void Print(T first,T last) {
 56     for(;first!= last; ++ first)
 57         cout << * first << ",";
 58     cout << endl;
 59 }
 60 int main()
 61 {
 62     
 63     Student s[] = { {"Tom",80},{"Jack",70},
 64                     {"Jone",90},{"Tom",70},{"Alice",100} };
 65     
 66     MyMultimap<string,int> mp;
 67     for(int i = 0; i<5; ++ i)
 68         mp.insert(make_pair(s[i].name,s[i].score));
 69     Print(mp.begin(),mp.end()); //按姓名从大到小输出
 70 
 71     mp.Set("Tom",78); //把所有名为"Tom"的学生的成绩都设置为78
 72     Print(mp.begin(),mp.end());
 73     
 74     
 75     
 76     MyMultimap<int,string,less<int> > mp2;
 77     for(int i = 0; i<5; ++ i) 
 78         mp2.insert(make_pair(s[i].score,s[i].name));
 79     
 80     Print(mp2.begin(),mp2.end()); //按成绩从小到大输出
 81     mp2.Set(70,"Error");          //把所有成绩为70的学生,名字都改为"Error"
 82     Print(mp2.begin(),mp2.end());
 83     cout << "******" << endl;
 84     
 85     mp.clear();
 86     
 87     string name;
 88     string cmd;
 89     int score;        
 90     while(cin >> cmd ) {
 91         if( cmd == "A") {
 92             cin >> name >> score;
 93             if(mp.find(name) != mp.end() ) {
 94                 cout << "erroe" << endl;
 95             }
 96             mp.insert(make_pair(name,score));
 97         }
 98         else if(cmd == "Q") {
 99             cin >> name;
100             MyMultimap<string,int>::iterator p = mp.find(name);
101             if( p!= mp.end()) {
102                 cout << p->second << endl;
103             }
104             else {
105                 cout << "Not Found" << endl; 
106             }        
107         }
108     }
109     return 0;
110 }
View Code

不知道是否可以直接继承……?

posted @ 2018-04-20 14:10  TobicYAL  阅读(3612)  评论(2编辑  收藏  举报