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 }