問題描述
某股票交易所請你編寫一個程序,根據開盤前客戶提交的訂單來確定某特定股票的開盤價和開盤成交量。
該程序的輸入由很多行構成,每一行爲一條記錄,記錄可能有以下幾種:
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。
分析
從高價往低價買,從低價往高價賣,直到賣價高於買價,得到開盤價。
代碼
#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#include<string>
using namespace std;
struct node
{
int type;//0賣 1買 -1取消
double p;
long long s;
node(){}
node(int type,double p,long long s):type(type),p(p),s(s){}
bool operator< (const node &n)const
{
if(!type) return p>n.p;
return p<n.p;
}
};
priority_queue<node> s_que,b_que;
int main()
{
string str;
node ns[5007];
int i=0,x;
double p;
long long sum=0;
while(cin>>str)//輸入數據
{
i++;
if(str[0]=='b')
{
cin>>ns[i].p>>ns[i].s;
ns[i].type=1;
}
else if(str[0]=='s')
{
cin>>ns[i].p>>ns[i].s;
ns[i].type=0;
}
else
{
cin>>x;
ns[i].type=ns[x].type=-1;
}
}
for(int j=1;j<=i;j++)//入隊
{
if(ns[j].type==0) s_que.push(ns[j]);
if(ns[j].type==1) b_que.push(ns[j]);
}
while(!s_que.empty()&&!b_que.empty())//匹配
{
node s=s_que.top(),b=b_que.top();
s_que.pop(); b_que.pop();
if(s.p>b.p) break;
sum+=min(s.s,b.s);
p=b.p;
if(s.s>b.s)
{
s.s-=b.s;
s_que.push(s);
}
else if(s.s<b.s)
{
b.s-=s.s;
b_que.push(b);
}
}
printf("%.2f %lld",p,sum);//long long 必須用%lld!
return 0;
}
題解彙總
CCF-CSP認證歷年題解