STL堆之五
//有一些随时更新的数据,求排序后在中间的那个数据
//可以把数据分成两半,使用两个堆,最大堆和最小堆,一半比中间值小,一半比中间值大,
//插入数据时,只需要和前一半(最大堆)的最大值和后一半(最小堆)的最小值比较即可
//必须保证第1个堆(大顶堆)的堆顶结点要小于第2个堆(小顶堆)的堆顶结点,
//这样小顶堆的结点就全部大于大顶堆的结点,且小顶堆的结点数只能与大顶堆的结点数相等或者比它大 1
//这样任何时候,如果两堆大小相等,则说明是偶数,不存在中间结点
//如果小顶堆的结点个数大于大顶堆(>1),则中间结点就是小顶堆的堆顶结点
#include<iostream> //sicily 1022. Poor contestant Prob
#include<algorithm>
#include<cstring>
#include<stdio.h>
using namespace std;
#define maxn 100010
struct node
{
char name[11];
int mark;
node() //默认构造函数
{
}
node(int m,char c[])
{
mark=m;strcpy(name,c);
}
const node operator=(const node& other)
{
mark=other.mark;strcpy(name,other.name);
return *this;
}
}heap[2][maxn]; //heap[0],heap[1]分别表示大顶堆和小顶堆
bool myless(const node& a,const node& b) //大顶堆比较函数
{
return a.mark<b.mark;
}
bool mygreater(const node& a,const node& b) //小顶堆比较函数
{
return a.mark>b.mark;
}
int tail[2]; //tail[0],tail[1]分别表示大顶堆和小顶堆的长度
void insert(node p,int id) //id=1,压入小顶堆,id=0,压入大顶堆
{
heap[id][tail[id]++]=p;
if (id==1)
push_heap(heap[id],heap[id]+tail[id],mygreater);
//进堆是先把要放进堆的元素放到容器的尾端(heap[id][tail[id]]),接着tail[id]++,然后再调用push_heap,把整体的堆区间作为参数传进去,调整好成新堆
else
push_heap(heap[id],heap[id]+tail[id],myless);
}
void remove(int id) //id=1,从小顶堆弹出,id=0,从大顶堆弹出
{
if (id==1)
pop_heap(heap[id],heap[id]+tail[id]--,mygreater);
//出堆的做法是先调用pop_heap,把堆顶点移到最后(这时tail[id]值还没发生改变),然后tail[id]--,相当于从容器弹出最后的元素
else
pop_heap(heap[id],heap[id]+tail[id]--,myless);
}
int main()
{
int cases,mark;char ch[11],name[11];
cin>>cases;
while(cases--)
{
tail[0]=tail[1]=0;
while(scanf("%s",ch))
{
if(strcmp(ch,"Add")==0)
{
scanf("%s%d",name,&mark);
node p(mark,name);
if(tail[0]==tail[1]) //若两个堆结点数相等,则新结点压入小顶堆
{
if(tail[0]==0)
insert(p,1);
else //比较新结点与大顶堆的堆顶点的大小
{
if(mark>heap[0][0].mark)
insert(p,1);
else //若新结点小于大顶堆的堆顶点,则先要把大顶堆的堆顶点压入小顶堆,再弹出大顶堆的堆顶点,最后把新结点压入大顶堆,保证了大顶堆的所有结点全部小于小顶堆的结点
{
node q=heap[0][0];
insert(q,1);
remove(0);
insert(p,0);
}
}
}
else //两个堆的结点数不等,则新结点压入大顶堆,因为结点数较少的只可能是大顶堆
{
if(mark<heap[1][0].mark)
insert(p,0);
else //若新结点大于小顶堆的堆顶点,则先要把小顶堆的堆顶点压入大顶堆,再弹出小数点顶堆的堆顶点,最后把新结点压入小顶堆
{
node q=heap[1][0];
insert(q,0);
remove(1);
insert(p,1);
}
}
}
else if(strcmp(ch,"Query")==0)
{
if (tail[0]==tail[1])
printf("No one!\n");
else
printf("%s\n",heap[1][0].name);
}
else if(strcmp(ch,"End")==0)
{
if (tail[0]==tail[1])
printf("Happy BG meeting!!\n");
else
printf("%s is so poor.\n",heap[1][0].name);
break;
}
}
if(cases)
printf("\n");
}
return 0;
}