14年12月CCF真题3-集合竞价

问题描述

  某股票交易所请你编写一个程序,根据开盘前客户提交的订单来确定某特
定股票的开盘价和开盘成交量。

该程序的输入由很多行构成,每一行为一条记录,记录可能有以下几种:

1. buy p s 表示一个购买股票的买单,每手出价为p,购买股数为s。
2. sell p s 表示一个出售股票的卖单,每手出价为p,出售股数为s。
3. cancel i表示撤销第i行的记录。 如果开盘价为p0,则系统可以将所有出价至少为p0的买单和所有出价至多

为p0的卖单进行匹配。因此,此时的开盘成交量为出价至少为p0的买单的总股 数和所有出价至多为p0的卖单的总股数之间的较小值。

你的程序需要确定一个开盘价,使得开盘成交量尽可能地大。如果有多个 符合条件的开盘价,你的程序应当输出最高的那一个。
输入格式

输入数据有任意多行,每一行是一条记录。保证输入合法。股数为不超过 108的正整数,出价为精确到恰好小数点后两位的正实数,且不超过 10000.00。
输出格式

  你需要输出一行,包含两个数,以一个空格分隔。第一个数是开盘价,第
二个是此开盘价下的成交量。开盘价需要精确到小数点后恰好两位。

输入样例
buy 9.25 100
buy 8.88 175
sell 9.00 1000
buy 9.00 400
sell 8.92 400
cancel 1
buy 100.00 50
输出样例
9.00 450
评测用例规模与约定
对于 100%的数据,输入的行数不超过 5000。 

应该不会有取消一条取消指令这种事吧。。。

 1 #include <iostream>
 2 #include <vector>
 3 #include <map>
 4 #include <iomanip>
 5 
 6 using namespace std;
 7 class line     //定义数据结构存放指令
 8 {
 9 public:
10     string action;
11     double p;
12     int s;
13 };
14 int main() {
15     int num=0;     //在mac下用clion写的,貌似不认ctrl+z和ctrl(command)+d,只好手动输入行数了
16     cin>>num;
17     string in;
18     map<double,int,greater<double>> buy;     //降序储存buy的每种价格的购买量
19     map<double,int> sell;     //升序储存sell的每种价格的卖出量
20     map<double,int> all;
21     vector<line*> v;
22     for(int i=0;i<num;i++)
23     {
24         cin>>in;
25         if(in =="buy")
26         {
27             double a;
28             int b;
29             cin>>a>>b;
30             buy[a]+=b;
31             all[a]+=b;
32             line *temp = new line;
33             temp->action = "buy";
34             temp->p = a;
35             temp->s = b;
36             v.push_back(temp);     //存放指令
37         }
38         else if(in == "sell")
39         {
40             double a;
41             int b;
42             cin>>a>>b;
43             sell[a]+=b;
44             all[a]+=b;
45             line *temp = new line;
46             temp->action = "sell";
47             temp->p = a;
48             temp->s = b;
49             v.push_back(temp);     //存放指令
50         }
51         else
52         {   int n;     //撤销指令,从map中减去相应量
53             cin>>n;
54             n--;
55             double a = v[n]->p;
56             int b = v[n]->s;
57             if(v[n]->action=="buy")
58                 buy[a]-=b;
59             else
60                 sell[a]-=b;
61         }
62     }
63     double P=0;     //定义P和S
64     int S=0;
65     for(map<double,int>::iterator it = all.begin();it!=all.end();it++)
66     {     //对sell从小到大扫描
67         int temp=0;     //定义三种临时值储存成交量
68         int temp1=0;
69         int temp2=0;
70         for(map<double,int>::iterator iit = sell.begin();iit!=sell.end();iit++)
71         {     //计算出价至多为p0的卖单的总股数
72             if(iit->first<=it->first)
73                 temp1+=iit->second;
74             else
75                 break;
76         }
77         for(map<double,int>::iterator iit = buy.begin();iit!=buy.end();iit++)
78         {     //计算出价至少为p0的买单的总股数
79             if(iit->first>=it->first)
80                 temp2+=iit->second;
81             else
82                 break;
83         }
84         temp = min(temp1,temp2);
85         if(temp>=S)
86         {
87             P = it->first;
88             S = temp;
89         }
90     }
91     cout<<fixed<<setprecision(2)<<P<<" "<<S; //格式化输出
92     return 0;
93 }
原文地址:https://www.cnblogs.com/Outer-Haven/p/4695351.html