108. 虚数 //set跟priority_queue的使用及重载运算符

时间限制 1000 ms 内存限制 65536 KB

题目描述

给你一个复数集合{Aj+i*Bj},保证Aj和Bj都是整数,初始为空集。

每次会给你如下两种操作中的一种:

       1."Insert x+iy",其中x,y都是整数。表示在集合中加入一个复数 x+iy,同时输出此时集合的大小;

       2."Pop"。如果集合为空集直接返回“Empty!”,如果有元素则以"x+iy"的形式显示集合中模值最大的复数,然后将该元素从集合中删除,之后在第二行显示操作之后的集合大小,如果为空集则显示“Empty!”。

输入格式

第一行只有一个数T,代表case数。0<=T<=10

每一组case:

       第一行有一个整数n,表示这组case中一共有n条命令 0

       接下来n行每行有一个命令,命令如上所述

保证不会输入两个模值同样的元素,并保证实部虚部都大于0,小于1000。

输出格式

依照上述原则输出每一个命令对应的输出

如果输入命令是Insert命令,则对应的输出占一行为集合大小;

如果输入命令是Pop命令,则对应的输出占一行或者两行,为模值最大的复数和集合大小。

请注意,输出集合大小的格式为"Size:空格x回车",x为集合大小

输入样例

1
5
Pop
Insert 1+i2
Insert 2+i3
Pop
Pop

输出样例

Empty!
Size: 1
Size: 2
2+i3
Size: 1
1+i2
Empty!

 set与priority_queue的区别:

第一点,priority_queue是不提供删除任意一项的,它提供的方法非常有限,只有push,pop,top等几个,而set有erase方法。同时erase有三种形式可用。

void erase( iterator i ); //删除迭代器为i元素;(根据下标删除)

void erase( iterator start, iterator end ); //删除从迭代器start开始到end结束的元素;

size_type erase( const key_type &key ); //删除等于key值的所有元素(返回被删除的元素的个数)。(根据元素值删除)

第二点,可怜的priority_queue竟然没有提供iterator,想要遍历的唯一方法就是不断的top和pop直到容器为空。从性能上考虑,priority_queue遍历时必须删除,导致了额外的删除开销,而一个iterator迭代器却不需要对容器结构做任何修改,性能上更胜一筹。

第三点,还是性能,priority_queue实际上是一个wrapper,它需要底层的容器支持,默认的容器是vector,我们知道vector本身类似于数组,要插入数据的开销是O(n)。再来看一下set,它使用的是B树,我们知道,B树在插入的时候开销是O(nlogn),可见,孰高孰低也是不言而喻的。

综上,推荐使用set,set可以实现priority_queue的各种功能,且还可以进行遍历操作与按关键字删除操作。

set不会重复插入相同键值的元素,而multiset 允许相同键值的元素插入;queue与priority_queue都允许相同键值的元素插入。

set与multiset默认为从小到大排列,而priority_queue默认为从大到小排列。

#include//set方法 
using namespace std;
struct xu
{
	int a,b,m;
	//重载运算符的格式bool operator<(const 结构体名 &x)const
	//一个单词都不能丢,并且重载STL中自带排序的容器时只能重载小于号,无法重载大于号 
	bool operator<(const xu &x)const
	{
		return m>x.m;
	}
};

int cmp(xu x,xu y)
{
	return x.m>y.m;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		char op[10],x,y;
		setse;
		se.clear();//清空,set无pop() 
		scanf("%d",&n);//刚开始忘记输入n了,运行样例没报错且结果正确,但是提交一直超时,害我找                    
                       //了半天错误。敲码不细心,提交两行泪(┬_┬)
		while(n--)
		{
			scanf("%s",op);
			string s=op;
			if(s=="Pop")
			{
				if(se.empty()!=true)
				{
					xu xu1=*se.begin();//set无top()或front() 
					printf("%d+i%d\n",xu1.a,xu1.b);
					se.erase(se.begin());//set无pop() 
					if(se.empty()!=true)printf("Size: %d\n",se.size());
					else printf("Empty!\n");
				}
				else printf("Empty!\n");
				
			}
			if(s=="Insert")
			{
				xu xu1;
				int a,b,m;
				scanf("%d+i%d",&a,&b);
				m=a*a+b*b;
				xu1.a=a;
				xu1.b=b;
				xu1.m=m;
				se.insert(xu1);
				printf("Size: %d\n",se.size());
			}
		}
	}
} 
#include//priority_queue方法 
using namespace std;
struct xu
{
	int a,b,m;
	bool operator < (const xu &x)const
	{
		return my.m;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		char op[10],x,y;
		priority_queuese;
		while(se.empty()!=true)se.pop();//queue无clear() 
		scanf("%d",&n);
		while(n--)
		{
			scanf("%s",op);
			string s=op;
			if(s=="Pop")
			{
				if(se.empty()!=true)
				{
					xu xu1=se.top();//priority_queue只能用top();queue只能用front() 
					printf("%d+i%d\n",xu1.a,xu1.b);
					se.pop();
					if(se.empty()!=true)printf("Size: %d\n",se.size());
					else printf("Empty!\n");
				}
				else printf("Empty!\n");
				
			}
			if(s=="Insert")
			{
				xu xu1;
				int a,b,m;
				scanf("%d+i%d",&a,&b);
				m=a*a+b*b;
				xu1.a=a;
				xu1.b=b;
				xu1.m=m;
				se.push(xu1);
				printf("Size: %d\n",se.size());
			}
		}
	}
} 

你可能感兴趣的:(北邮机试/OJ,算法与数据结构)