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<=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());
			}
		}
	}
} 
發佈了160 篇原創文章 · 獲贊 7 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章