時間限制 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<=100
接下來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<bits/stdc++.h>//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;
set<xu>se;
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<bits/stdc++.h>//priority_queue方法
using namespace std;
struct xu
{
int a,b,m;
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;
priority_queue<xu>se;
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());
}
}
}
}