CCF CSP 201412-3 集合竞价
思路:
1.用结构体存储信息;
2.先用vector存储所有信息,最后再写入优先队列中,这样可以方便的处理cancel命令;
3.输出的价格一定是买家里的,因此将买家的出价从大到小遍历,每遍历到一个价格,数数价格小于等于这个价格的卖家的总股数就好了,两个优先队列可以方便的实现这个过程;
4.注意输出精度,注意数据范围;
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define p_b(a) push_back(a)
struct Order{
char name;
double p;
ll num;
Order(char name='0',double p=0,ll num=0):name(name),p(p),num(num){}
bool operator<(const Order & a)const{
return p<a.p;
}
};
vector<Order> pre_ord;
priority_queue<Order> buy_list;//价高的在前面
priority_queue<Order> sell_list;
int main(){
string s;
while(cin>>s){
if(s[0]=='c'){
int index;
cin>>index;
pre_ord[index-1].num=0;
pre_ord.p_b(Order());//cancel也要占一个位置
continue;
}
double p;
ll num;
cin>>p>>num;
pre_ord.p_b(Order(s[0],p,num));
}
ll buy_ans=0,sell_ans=0;
for(auto e:pre_ord){
if(!e.num) continue;
if(e.name=='b') buy_list.push(e);
else{
sell_list.push(e);
sell_ans+=e.num;
}
}
ll num=0;
double p=0;
while(!buy_list.empty()){
buy_ans+=buy_list.top().num;//试试顶部的价格
while(!sell_list.empty()&&sell_list.top().p>buy_list.top().p){
sell_ans-=sell_list.top().num;
sell_list.pop();
}
ll minn=min(buy_ans,sell_ans);
if(minn<=num) break;//不合适就退出
num=minn;
p=buy_list.top().p; //合适就记录下来
buy_list.pop();
}
printf("%.2f %lld",p,num);
return 0;
}