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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM