时间限制 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());
}
}
}
}