20210412set和multiset以及map拓展

计蒜客 - T1229
现有一整数集(允许有重复元素),初始为空。我们定义如下操作:
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
行,每行按要求输出。

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

本题需要用到multiset,multiset是set库中一个非常有用的类型,它可以看成一个序列,插入一个数,删除一个数都能够在O(logn)的时间内完成,而且他能时刻保证序列中的数是有序的,而且序列中可以存在重复的数。
借鉴:https://blog.csdn.net/sodacoco/article/details/84798621
代码:

#include<bitsdc++.h>
#include<cstring>
#include<set>
using namespace std;
int main() {
	int n,x;
	char m[3];
	set<int>a;
	multiset<int>b;
	cin >> n;
	while(n--) {
		cin >> m;
		if(strcmp(m,"add")==0) {
			cin >> x;
			a.insert(x);
			b.insert(x);
			cout << b.count(x) << endl;
		}
		else if(strcmp(m,"del")==0) {
			cin >> x;
			cout << b.count(x) << endl;
			b.erase(x);
		}
		else {
			cin >> x;
			set<int>::iterator it;
			it=a.find(x);
			if(it==a.end()) {
				cout << "0 " << b.count(x) << endl;
			}
			else cout << "1 " << b.count(x) << endl;
		}
	}
}

计蒜客 - T1230
蒜头君新开了一家热血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。

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

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

输入格式
第一行一个数
n
(
0
<
n

100000
)
,表示格斗场新来的会员数(不包括蒜头君)。

以后
n
行每一行两个数,按照入会的时间给出会员的
id
(
2

id

10
6
)
和实力值(

10
9
)。一开始,蒜头君就算是会员,
id

1
,实力值
1000000000

输入保证两人的实力值不同。

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

Sample Input
3
2 1
3 3
4 2
Sample Output
2 1
3 2
4 2

一个模板题,主要从这个题上了解到map这库的更多作用,具体看代码。

#include<cstdio>
#include<iostream>
#include<map>
#define LL long long
using namespace std;

map<int,int> mp;//map函数会以第一个int自动排序(从小到大) 

int main()
{
	int n;
	while(cin >> n && n) {
		int id,g;
		mp.clear();
		mp[1000000000] = 1;
		while(n--) {
			cin >> id >> g;
			mp[g] = id;
			int ans = 0;
			map<int,int>::iterator it = mp.find(g);
			if(it == mp.begin()) ans = (++ it) -> second;//如果找到的g位置是第一个(也就是最小的值),则找比他的一的id
				else {
					map<int,int>::iterator it2 = it;
					it2 --;
					it ++;
					if(it -> first - g >= g - it2 -> first) {//值接近的id 
						ans = it2 -> second;
					}
					else ans = it -> second;
				}
			cout << id << " " << ans << endl;	  
		}
		
	}
	return 0;
}

链接:https://blog.csdn.net/sevenjoin/article/details/81943864?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161822471616780261987424%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161822471616780261987424&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-81943864.first_rank_v2_pc_rank_v29&utm_term=c%2B%2Bmap

上一篇:C++知识点 STL容器2—set


下一篇:STL源码剖析学习记录(二)