CCF CSP 201412-3 集合竞价

mac2026-06-05  8

思路:

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; }
最新回复(0)