201412-3 集合竞价 100分 46ms

点击前往试题目录:https://blog.csdn.net/best335/article/details/99550556
在这里插入图片描述
易错点:
-----1、cancel命令不能够撤销cancel命令
-----2、股数为不超过10^8的正整数,输入的行数不超过5000,使用int导致股数溢出。
-----3、如果有多个符合条件的开盘价,你的程序应当输出最高的那一个。
-----4、如果使用map注意lower_bound的使用

#include<iostream>
#include<cstring>
#include<map>
#include<iomanip>
#include<ctype.h>
using namespace std;
inline long long min(const long long&l1,const long long&l2){return l1<l2?l1:l2;}
void toLower(string&s){ for(int i=0,ni=s.size();i<ni;++i) s[i]=tolower(s[i]);}
int main(){
	int n=0,C[5000],U[5000],S[5000];//命令类型 使用标志0使用 1弃用
	long long ans=0L;
	double P[5000],p;
	cout.flags(ios::fixed);
	cout.precision(2);
	memset(U,0,sizeof(U));
	memset(S,-1,sizeof(S));
	for(int i=0;;++i,++n){
		string c;
		if(!(cin>>c)) break;
		toLower(c);
		if(c=="buy")
			cin>>P[i]>>S[i],C[i]=1;
		else if(c=="sell")
			cin>>P[i]>>S[i],C[i]=2;
		else if(c=="cancel")
			cin>>S[i],C[i]=3,U[--S[i]]=1;
	}
	map<double,long long> MS,MB;
	for(int i=0;i<n;++i){
		if(U[i]==0){
			if(C[i]==1) MB[P[i]]+=S[i];
			else if(C[i]==2) MS[P[i]]+=S[i];
		}
	}
	//买单:至少为map->first的买单的总股数
	for(map<double,long long>::reverse_iterator xit=MB.rbegin(),it=MB.size()<1?MB.rbegin():(xit++);xit!=MB.rend();++it,++xit)xit->second+=it->second;
	//卖单:至多为map->first的卖单的总股数
	for(map<double,long long>::iterator xit=MS.begin(),it=MS.size()<1?MS.begin():(xit++);xit!=MS.end();++it,++xit) xit->second+=it->second;
	//开盘成交量为出价至少为p0的买单的总股数和所有出价至多为p0的卖单的总股数之间的较小值。
	for(map<double,long long>::iterator itS,itB=MB.begin();itB!=MB.end();++itB){
		const double &p0=itB->first;
		if((itS=MS.lower_bound(p0))==MS.end()||itS->first!=p0&&(itS--)==MS.begin()) continue;//卖单必须存在 
		long long tmpS=min(itB->second,itS->second);
		if(tmpS>=ans){
			p=p0;
			ans=tmpS;
		}
	}
	cout<<p<<" "<<ans<<endl;
	return 0;
}
处理cancel对cancel有效的方法
map<int,vector<int> >MC;
bool B(const int&k){
	map<int,vector<int> >::iterator it=MC.find(k);
	if(it==MC.end()) return true;
	vector<int>&v=it->second;
	for(int i=0,ni=v.size();i<ni;++i){
		if(B(v[i])) return false;
	}
	return true;
}
//for(int i=0;i<n;++i){if(C[i]==3)MC[S[i]].push_back(i);}
//for(int i=0;i<n;++i){ if(C[i]!=3&&!B(i)) U[i]=1;}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值