试题编号: | 201412-3 |
试题名称: | 集合竞价 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 某股票交易所请你编写一个程序,根据开盘前客户提交的订单来确定某特定股票的开盘价和开盘成交量。 输入格式 输入数据有任意多行,每一行是一条记录。保证输入合法。股数为不超过108的正整数,出价为精确到恰好小数点后两位的正实数,且不超过10000.00。 输出格式 你需要输出一行,包含两个数,以一个空格分隔。第一个数是开盘价,第二个是此开盘价下的成交量。开盘价需要精确到小数点后恰好两位。 样例输入 buy 9.25 100 样例输出 9.00 450 评测用例规模与约定 对于100%的数据,输入的行数不超过5000。 |
这个是看了https://blog.csdn.net/tigerisland45/article/details/54928820之后才写出来的。。。
其中是把买家的价钱从高到低排,卖家是从低到高排,然后一直到买家最高的价钱都不能买卖家最低价为止,其中我很疑惑为什么要让最高价钱来买最低价钱,不应该是最高价来买最贵的股票,然后让比较没钱的买家来买比较便宜的股票,以达到成交量较大的目的吗?但是~注意!!比较没钱的买家买不起土豪们买得起得股票,就不满足开盘价的概念了,开盘价是所有大于此的买家和所有低于此的卖家,即买家的价钱一定要高于卖家!
#include <iostream>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <string.h>
#include <vector>
#define maxn 5005
using namespace std;
struct Node
{
int order;//序号
float money;//钱
long long num;//股票的数量
int action;//卖是0,买是1
bool operator < (const Node & n) const
{
if(action == 1)//买的话越高越好
{
return money < n.money;
}
else
return money > n.money;
}
};
priority_queue<Node>sell,buy;
bool useless[maxn];
int main(int argc, char** argv)
{
string s;
int no = 0;//编号
float Tmoney;
int Tnum;
int Trow;
Node temp;
memset(useless,0,sizeof(useless));
while(cin>>s)
{
if(s == "buy")
{
temp.action = 1;
cin>>temp.money>>temp.num;
temp.order = ++no;
buy.push(temp);
}
else if(s == "sell")
{
temp.action = 0;
cin>>temp.money>>temp.num;
temp.order = ++no;
sell.push(temp);
}
else if(s == "cancel")
{
no++;
cin>>Trow;
useless[Trow] = 1;
}
else
break;
}
//开始处理
temp.money = 0;
temp.num = 0;
Node tb,ts;
for(;;)
{
//找出非空的最高价买
while(!buy.empty())
{
tb = buy.top();
if(useless[tb.order] == 1)
{
buy.pop();
}
else
{
break;
}
}
//找出非空的最低价买卖
while(!sell.empty())
{
ts = sell.top();
if(useless[ts.order])
sell.pop();
else
break;
}
if(sell.empty()||buy.empty()) break;
//匹配
if(tb.money>=ts.money)
{
temp.money = tb.money;
temp.num+= min(tb.num,ts.num);
//买得多
if(tb.num>ts.num)
{
tb.num = tb.num - ts.num;
sell.pop();
buy.pop();
buy.push(tb);
}
else if(tb.num==ts.num)
{
buy.pop();
sell.pop();
}
else
{
ts.num = ts.num - tb.num;
buy.pop();
sell.pop();
sell.push(ts);
}
}
else
{
break;
}
}
// 输出结果
printf("%.2f", temp.money);
cout << " " << temp.num << endl;
return 0;
}
/**
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
**/
今天又写了一个比较简单的程序
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int action;//0是卖,1是买,-1是cancel
float price;
long long num;
};
vector<Node>nodes;
int main()
{
set<float>P;//放价钱的地方
Node t;
string s;
int i;
while(cin>>s)
{
if(s == "buy")
{
cin>>t.price>>t.num;
t.action = 1;
P.insert(t.price);
}
else if(s == "sell")
{
cin>>t.price>>t.num;
t.action = 0;
P.insert(t.price);
}
else
{
cin>>i;
t.action = -1;
nodes[i-1].action = -1;
}
nodes.push_back(t);
}
//开始匹配
float tPrice = 0; //开盘价
float temp;//临时价钱
long long tnum = 0; //开盘数量
long long tsellNum,tbuyNum;
for(set<float>::iterator it = P.begin();it!=P.end();it++)
{
temp = *it;
tsellNum = 0;tbuyNum = 0;
for(i = 0;i<nodes.size();i++)
{
//买单
if(nodes[i].action == 1 && nodes[i].price>=temp)
{
tbuyNum +=nodes[i].num;
}//卖单
else if(nodes[i].action == 0 && nodes[i].price<=temp)
{
tsellNum += nodes[i].num;
}
}
long long totalNum = min(tbuyNum,tsellNum);//一共成交量是这个
if(totalNum>tnum)
{
tnum = totalNum;
tPrice = temp;
}
else if(totalNum==tnum && temp >tPrice)
{
tPrice = temp;
}
}
printf("%.2f ",tPrice);
cout<<tnum;
return 0;
}
/**
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
**/
这个很轻松就AC了。。