第12周&第13周

12&13:STL

Standard Template Library

sort, binary_search/lower_bound/upper_bound, multiset, set, multimap, map.

作业

1.sort简单题

Description:程序填空,产生指定输出结果。

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int a[8] = {6,5,14,23,2,9,87,10 };
 8     sort(
 9 // Your Code Here
10 );
11     for(int i = 0;i < 8; ++i)
12         cout << a[i] << "," ; 
13     return 0;
14 }

Input:(无)

Output:6,87,23,14,9,5,2,10,

Sample Input:(无)

Sample Output:6,87,23,14,9,5,2,10,

a+1, a+7, greater<int>()

2.还是sort简单题

Description:程序填空,产生指定输出结果。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 struct Point{
 7     int x;
 8     int y;
 9 };
10 // Your Code Here
11 int main()
12 {
13     int a[8] = {6,5,55,23,3,9,87,10 };
14     sort(a,a+8,Rule1());
15     for(int i = 0;i < 8; ++i)
16         cout << a[i] << "," ; 
17     cout << endl;
18     Point ps[8] = {{1,0},{0,1},{0,-1},{-1,0},{1,-1},{1,1},{2,0},{-2,0} } ;
19     sort(ps,ps+8,Rule2());
20     for(int i = 0;i < 8; ++i)
21         cout << "(" << ps[i].x << "," << ps[i].y << ")"; 
22     return 0;
23 }

Input:(无)

Output:

10,23,3,55,5,6,87,9,
(-1,0)(0,-1)(0,1)(1,0)(1,-1)(1,1)(-2,0)(2,0)

整数按照个位数从小到大排。个位数相同,则大的排前面。点按照离原点从近到远排。距离相同,则按x坐标从小到大排。x坐标也相同,则按y坐标从小到大排。

Sample Input:(无)

Sample Output:

10,23,3,55,5,6,87,9,
(-1,0)(0,-1)(0,1)(1,0)(1,-1)(1,1)(-2,0)(2,0)

 1 struct Rule1 {
 2     bool operator() (const int &n1, const int &n2) {
 3         if(n1%10 != n2%10)
 4             return (n1%10) < (n2%10);
 5         else
 6             return n1 > n2;
 7     }
 8 };
 9 
10 double distance(Point p)
11 {
12     return sqrt(p.x*p.x+p.y*p.y);
13 }
14 
15 struct Rule2 {
16     bool operator() (const Point &p1, const Point &p2) {
17         if(abs(distance(p1)-distance(p2)) < 1e-6) {
18             if(p1.x != p2.x)
19                 return p1.x < p2.x;
20             else
21                 return p1.y < p2.y;
22         }
23         else
24             return distance(p1) < distance(p2);
25     }
26 };

3.点集的查询

Description:先给定平面上一些点的坐标 然后给定一些查询命令,根据查询命令输出Yes或No,要求使用sort和binary_search实现。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 using namespace std;
 5 struct Point 
 6 {
 7     int x;
 8     int y;
 9 }points[100100];
10 bool func(const Point & P1,const Point & p2);
11 struct Rule {
12     bool operator () ( const Point & p1,const Point & p2) {
13         return func(p1,p2);
14     }
15 };
16 int main()
17 {
18     int n,m;
19     scanf("%d%d",&n,&m);
20     for(int i = 0;i < n; ++i) 
21         scanf("%d%d",&points[i].x, &points[i].y);
22 // Your Code Here

Input:

第一行是整数n和m,0<n,m<=100000。接下来是n行,每行两个整数x,y代表一个点的坐标。0<x,y<=10^9。

数据确保对于任意两点 (x1,y1)和(x2,y2)表达式x1>x2 && y1<y2 || x1<x2 && y1>y2一定为真。

再接下来是m行,每行格式为x n或y n,分别表示询问x坐标为n的点是否存在和y坐标为n的点是否存在。 0<n<=10^9。

Output:对每个询问,输出 "Yes"或"No"。

Sample Input:

5 6
8 22
12 20
5 24
13 19
2 30
x 12
x 7
y 20
y 7
y 19
x 8

Sample Output:

Yes
No
Yes
No
Yes
Yes

 1 sort(points, points+n, Rule());
 2 for(int i=0; i<m; ++i) {
 3     int a;
 4     char cmd[10];
 5     scanf("%s %d", cmd, &a);
 6     Point pt;
 7     if(cmd[0] == 'x') {
 8         pt.x = a;
 9         if(binary_search(points, points+n, pt, Rule()))
10             printf("Yes
");
11         else
12             printf("No
");
13     }
14     else {
15         pt.x = -1;
16         pt.y = a;
17         if(binary_search(points, points+n, pt, Rule()))
18             printf("Yes
");
19         else
20             printf("No
");
21     }
22 }
23     return 0;
24 }
25 
26 bool func(const Point &p1, const Point &p2)
27 {
28     if(p1.x!=-1 && p2.x!=-1)
29         return p1.x < p2.x;
30     else
31         return p1.y > p2.y;
32 }

4.set

Description:

现有一整数集(允许有重复元素),初始为空。我们定义如下操作:

add x 把x加入集合;del x 把集合中所有与x相等的元素删除;ask x 对集合中元素x的情况询问。对每种操作,我们要求进行如下输出:

add 输出操作后集合中x的个数;del 输出操作前集合中x的个数;ask 先输出0或1表示x是否曾被加入集合(0表示不曾加入),再输出当前集合中x的个数,中间用空格格开。

Input:第一行是一个整数n,表示命令数。0<=n<=100000。后面n行命令,如Description中所述。

Output:共n行,每行按要求输出。

Sample Input:

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

Sample Output:

1
2
1 2
0 0
0
2
1 0

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <set>
 4 #include <string>
 5 #include <cstring>
 6 
 7 using namespace std;
 8 
 9 typedef multiset<int>::iterator PTR;
10 
11 int main()
12 {
13     int n;
14     multiset<int> mst;
15     set<int> st;
16     PTR p;
17     scanf("%d", &n);
18     
19     for(int i=0; i<n; ++i) {
20         char cmd[20];
21         int x;
22         scanf("%s %d", cmd, &x);
23         switch(cmd[1]) {
24             case 'd': 
25                 st.insert(x);
26                 mst.insert(x);
27                 printf("%d
", mst.count(x));
28                 break;
29             case 'e': 
30                 printf("%d
", mst.count(x));
31                 p = mst.find(x);
32                 if(p != mst.end()) {
33                     pair<PTR,PTR> range = mst.equal_range(x); 
34                     mst.erase(range.first, range.second);
35                 }
36                 break;
37             case 's': 
38                 set<int>::iterator pp = st.find(x);
39                 if(pp != st.end())
40                     printf("1 %d
", mst.count(x));
41                 else
42                     printf("0 %d
", mst.count(x));
43                 break;
44         }
45     }
46 
47     return 0;
48 }

5.热血格斗场

Description:

为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家热血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。我们假设格斗的实力可以用一个正整数表示,成为实力值。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有两个人的实力值与他差别相同,则他会选择比他弱的那个(显然,虐人必被虐好)。不幸的是,Facer一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮facer恢复比赛纪录,按照时间顺序依次输出每场比赛双方的id。

Input:

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

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

Sample Input:

3
2 1
3 3
4 2

Sample Output:

2 1

3 2 

4 2

 1 #include <iostream>
 2 #include <set>
 3 #include <cstdio>
 4 #include <cmath>
 5 
 6 using namespace std;
 7 
 8 struct Fighter
 9 {
10     int id;
11     int power;
12 };
13 struct Rule
14 {
15     bool operator()(const Fighter &f1, const Fighter &f2) {
16         return f1.power < f2.power;
17     }
18 };
19 
20 int main()
21 {
22     int n;
23     scanf("%d", &n);
24     set<Fighter, Rule> st;
25     Fighter ft;
26     ft.id = 1;
27     ft.power = 1000000000;
28     st.insert(ft);
29     for(int i=0; i<n; ++i) {
30         scanf("%d %d", &ft.id, &ft.power);
31         set<Fighter>::iterator pl = st.lower_bound(ft);
32         set<Fighter>::iterator pu = st.upper_bound(ft);
33         if(pl == st.begin())
34             printf("%d %d
", ft.id, pl->id);
35         else if(pu == st.end()){
36             --pu;
37             printf("%d %d
", ft.id, pu->id);
38         }
39         else {
40             --pl;
41             if(ft.power-pl->power <= pu->power-ft.power)
42                 printf("%d %d
", ft.id, pl->id);
43             else
44                 printf("%d %d
", ft.id, pu->id);
45         }
46         st.insert(ft);
47     }
48 
49     return 0;
50 }

6.冷血格斗场

Description:

为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家冷血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。我们假设格斗的实力可以用一个正整数表示,成为实力值,两人的实力值可以相同。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有多个人的实力值与他差别相同,则他会选择id最小的那个。不幸的是,Facer一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮facer恢复比赛纪录,按照时间顺序依次输出每场比赛双方的id。

Input:

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

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

Sample Input:

3
2 3
3 1
4 2

Sample Output:

2 1
3 2
4 2

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <map>
 4 #include <cmath>
 5 
 6 using namespace std;
 7 
 8 multimap<int, int> mp;
 9 
10 void toErase(multimap<int, int>::iterator p1, multimap<int, int>::iterator p2)
11 {
12     if(p1->first == p2->first) {
13         if(p1->second < p2->second)
14             mp.erase(p2);
15         else
16             mp.erase(p1);
17     }
18 }
19 
20 int main()
21 {
22     mp.insert(make_pair(1000000000,1));
23     int n;
24     scanf("%d",&n);
25 
26     for(int i=0; i<n; ++i) {
27         int id, power;
28         scanf("%d %d",&id, &power);
29         multimap<int,int>::iterator p = mp.insert(make_pair(power,id));
30         multimap<int,int>::iterator pL = p; -- pL;
31         multimap<int,int>::iterator pR = p; ++ pR;
32         if(p == mp.begin()) {
33             printf("%d %d
",id, pR->second);
34             toErase(p,pR);
35         }
36         else if(p == --mp.end()) {
37             printf("%d %d
", id, pL->second);
38             toErase(p,pL);
39         }
40         else {
41             int dL = abs(p->first-pL->first);
42             int dR = abs(p->first-pR->first);
43             if(dL<dR || dL==dR && pL->second<pR->second) {
44                 printf("%d %d
", id, pL->second);
45                 toErase(p,pL);
46             }
47             else if(dL>dR || dL==dR && pL->second>pR->second) {
48                 printf("%d %d
", id, pR->second);
49                 toErase(p,pR);
50             }
51         }
52     }
53 
54     return 0;
55 }
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <map>
 5 #include <set>
 6 #include <algorithm>
 7 
 8 using namespace std;
 9 
10 map<int,set<int> > mp;
11 
12 int main()
13 {
14     set<int> st;
15     st.insert(1);
16     mp.insert(make_pair(1000000000, st));
17     int n;
18     scanf("%d", &n);
19 
20     for(int i=0; i<n; ++i) {
21         int id,power;
22         scanf("%d %d",&id, &power);
23         map<int,set<int> >::iterator pL = mp.lower_bound(power);
24         if(pL == mp.end())
25             printf("%d %d
", id, *(mp.rbegin()->second.begin()));
26         else if(pL == mp.begin())
27             printf("%d %d
", id, *(mp.begin()->second.begin()));
28         else {
29             if(pL->first == power)
30                 printf("%d %d
", id, *(pL->second.begin()));
31             else {
32                 int d1 = abs(pL->first-power);
33                 map<int,set<int> >::iterator p = pL;
34                 --p;
35                 int d2 = abs(p->first-power);
36                 if(d1 < d2)
37                     printf("%d %d
", id, *(pL->second.begin()));
38                 else if(d1 > d2)
39                     printf("%d %d
", id, *(p->second.begin()));
40                 else {
41                     printf("%d %d
", id, min(*(pL->second.begin()), *(p->second.begin())));
42                 }
43             }
44         }
45         mp[power].insert(id);
46     }
47 
48     return 0;
49 }
原文地址:https://www.cnblogs.com/VincentValentine/p/5678485.html