问题描述
试题编号: | 201412-3 |
试题名称: | 集合竞价 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 某股票交易所请你编写一个程序,根据开盘前客户提交的订单来确定某特定股票的开盘价和开盘成交量。 输入格式 输入数据有任意多行,每一行是一条记录。保证输入合法。股数为不超过108的正整数,出价为精确到恰好小数点后两位的正实数,且不超过10000.00。 输出格式 你需要输出一行,包含两个数,以一个空格分隔。第一个数是开盘价,第二个是此开盘价下的成交量。开盘价需要精确到小数点后恰好两位。 样例输入 buy 9.25 100 样例输出 9.00 450 评测用例规模与约定 对于100%的数据,输入的行数不超过5000。 |
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Record {
int type; //存类型 1-buy 2-sell 3-撤销操作
long long s;
double p;
bool cancel; //false - 未撤销 true - 撤销
Record() {
}
Record(int t, long long ss, double pp, bool c=false) {
this->type = t;
this->s = ss;
this->p = pp;
this->cancel = c;
}
};
vector<Record> records;
bool cmp(int a, int b) {
return records[a].p > records[b].p;
}
int main() {
string s;
long long ss;
double p;
while (cin >> s) {
if (s[0] == 'c') { //撤销操作
int id;
scanf("%d", &id);
records.push_back(Record(3, 0, 0));
records[id - 1].cancel = true;
}
else {
scanf("%lf %lld", &p, &ss);
records.push_back(Record(s[0] == 'b' ? 1 : 2, ss, p));
}
}
vector<int> buy, sell;
long long buys = 0, sells = 0, ans = 0; //加入买,卖队列
double ansp = 0;
for (int i = 0; i < records.size(); i++) {
if (records[i].type == 1 && records[i].cancel == false) buy.push_back(i);
else if (records[i].type == 2 && records[i].cancel == false) {
sell.push_back(i);
sells += records[i].s;
}
}
//把价格从大到小排序
sort(buy.begin(), buy.end(), cmp);
sort(sell.begin(), sell.end(), cmp);
//寻找最大开盘价 买入价开始寻找
int j = 0;
for (int i = 0; i < buy.size(); i++) {
buys += records[buy[i]].s; //成交量 累计
for (; j < sell.size() && records[sell[j]].p > records[buy[i]].p; j++) {
sells -= records[sell[j]].s;//移除当前成交量
}
if (min(buys, sells) > ans) {
ans = min(buys, sells);
ansp = records[buy[i]].p;
}
}
printf("%.2lf %lld\n", ansp, ans);
return 0;
}