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;
}
原文地址:https://www.cnblogs.com/yuhan-blog/p/12308911.html