ACM练习 校赛183F:公平的游戏(TLE)【set的使用,给迭代器增加指定偏移量】

总时间限制: 1000ms 内存限制: 256000kB

描述

如果说考试还会受到天赋的影响,那最公平的游戏就非抽奖莫属了。

输入
第一行输入一个整数 N,代表操作的总数
接下来的 N 行中,第 i 行包含两个整数,分别为操作码 p 和操作数 k

操作码 p 定义如下:
0: 将号码 k 添加到记录中(忽略重复)
1: 将号码 k 从记录中删除
2: 宣布记录中第 k 大的号码中奖(保证该号码存在)
保证输入的操作码一定在上述定义中。

除满足上述条件外,0 < N <= 100000, -1000000000 <= k <= 1000000000

输出
对于每一个操作,若 p = 0 或 p = 1,不进行输出
对于每一个操作,若 p = 2,输出一行,包含一个整数,为该操作选出的中奖号码

样例输入

8
0 1
0 2
0 2
0 3
2 3
1 2
2 2
2 1

样例输出

1
1
3

SET的使用

顺序容器包括vector、deque、list、forward_list、array、string,所有顺序容器都提供了快速顺序访问元素的能力。

关联容器包括set、map

关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的。与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。

关联容器不支持顺序容器的位置相关的操作。原因是关联容器中元素是根据关键字存储的,这些操作对关联容器没有意义。而且,关联容器也不支持构造函数或插入操作这些接受一个元素值和一个数量值得操作。

关联容器支持高效的关键字查找和访问。两个主要的关联容器(associative container)类型是map和set。map中的元素是一些关键字----值(key–value)对:关键字起到索引的作用,值则表示与索引相关联的数据。set中每个元素只包含一个关键字:set支持高效的关键字查询操作----检查一个给定关键字是否在set中。

标准库提供set关联容器分为:

1、按关键字有序保存元素:set(关键字即值,即只保存关键字的容器);multiset(关键字可重复出现的set);

2、无序集合:unordered_set(用哈希函数组织的set);unordered_multiset(哈希组织的set,关键字可以重复出现)。

set就是关键字的简单集合。当只是想知道一个值是否存在时,set是最有用的。

在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。set中元素的值不能直接被改变。set内部采用的是一种非常高效的平衡检索二叉树:红黑树,也称为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树。

  • set具备的两个特点:

  • set中的元素都是排序好的
    set中的元素都是唯一的,没有重复的

set用法:

	begin();            // 返回指向第一个元素的迭代器
	end();              // 返回指向最后一个元素的迭代器
	clear();            // 清除所有元素
	count();            // 返回某个值元素的个数
	empty();            // 如果集合为空,返回true
	equal_range();      // 返回集合中与给定值相等的上下限的两个迭代器
	erase();			// 删除集合中的元素
	find();				// 返回一个指向被查找到元素的迭代器
	get_allocator();	// 返回集合的分配器
	insert();			// 在集合中插入元素
	lower_bound();		// 返回指向大于(或等于)某值的第一个元素的迭代器
	key_comp();			// 返回一个用于元素间值比较的函数
	max_size();			// 返回集合能容纳的元素的最大限值
	rbegin();			// 返回指向集合中最后一个元素的反向迭代器
	rend();				// 返回指向集合中第一个元素的反向迭代器
	size();				// 集合中元素的数目
	swap();				// 交换两个集合变量
	upper_bound();		// 返回大于某个值元素的迭代器
	value_comp();		// 返回一个用于比较元素间的值的函数

使用迭代器遍历set

// set::begin/end
#include <iostream>
#include <set>

int main()
{
	int myints[] = { 75,23,65,42,13 };
	std::set<int> myset(myints, myints + 5);

	std::cout << "myset contains:";
	for (std::set<int>::iterator it = myset.begin(); it != myset.end(); ++it)
		std::cout << ' ' << *it;

	std::cout << '\n';

	return 0;
}

Output:
myset contains : 13 23 42 65 75

给迭代器指定偏移量

在这里插入图片描述

本题代码

#include<iostream>
#include<set>
#include<algorithm>
#include <iterator>     // std::advance
using namespace std;

int main()
{
	set<int> arr;

	//输入总数
	int total;
	cin >> total;

	//循环
	int i;
	int p, k;
	std::set<int>::iterator pos;
	for (i = 0; i < total; i++)
	{
		cin >> p >> k;
		if (p == 0)//添加
		{
			arr.insert(k);
		}
		else if (p == 1)//删除k
		{
			arr.erase(arr.find(k));
		}
		else if (p == 2)//中奖
		{
			//找位置输出
			pos = arr.end();
			advance(pos,-k);
			/*for (int j = 0; j < k; j++)
			{
				pos--;
			}*/
			cout << *pos << "\n";
		}
	}
	system("pause");
}

猜你喜欢

转载自blog.csdn.net/sinat_42483341/article/details/89356277