试题编号: 201412-3
试题名称: 集合竞价
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
某股票交易所请你编写一个程序,根据开盘前客户提交的订单来确定某特定股票的开盘价和开盘成交量。
该程序的输入由很多行构成,每一行为一条记录,记录可能有以下几种:
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。
import sys
record=[]
strike=[]
for s in sys.stdin:
record.append(list(s.split()))#将记录写入record二维列表
for i in record:
if i[0]=='cancel':
i[0]=-1
record[int(i[1])-1][0]=-1#将要删除的记录的第一个字符串设置为-1
else:
i[1]=float(i[1])
i[2]=int(i[2])
for i in record[::-1]:#清理二维列表
if i[0]==-1:
record.remove(i)
record.sort(key=lambda x:x[1],reverse=True)#按照出价将所有的buy和sell从高到低排序
sell={}
num=0#计算sell总股数
for x,y,z in record[::-1]:#对于sell是小于开盘价的总股数
if x=='sell':
num+=z#将总股数用num记录
sell[y]=num#将出价作为字典的键,将小于当前sell的出价的总股数作为字典的值,#此时字典的键是按照从小到大的顺序排列
buy={}
num=0#计算buy总股数
for x,y,z in record:#对buy是大于开盘价的总股数
if x=='buy':
num+=z#计算总股数
buy[y]=num#此时字典的键是按照从大到小的顺序排列
num=0#成交量
price=0#开盘价
for i in record:
if min(sell[i[1]],buy[i[1]])>num:#找到较小值作为当开盘价是i[1]时的开盘成交量,
# 遍历所有i[1]找到最大成交量,确定此i[1]是最终开盘价
price=i[1]#此时的值就是开盘价
num=min(sell[i[1]],buy[i[1]])#当前i[1]作为开盘价的成交量
print("%.2f %d"%(price,num))
我从未止步。
-----szy2023.10.28
