隐藏页面特效

CCF 201412-3 集合竞价

问题描述
试题编号: 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。

 

 

本代码暴力枚举[minval,maxval]检索答案

注意:

刚开始以为会存在这样的情况:

 

存在一条删除命令 要删除买进或者卖出的股票
再来一条删除命令 要删除前面的删除命令/相当于前面的删除命令失效了
 
因为题目描述的不清楚,导致了我这样的幻觉~
 

网上有其他博主给出其他优质解决方案,如:证明了开盘价一定是买家的价格之一

#include<stdio.h> #include<algorithm> #include<iostream> #define mp make_pair #define fi first #define se second using namespace std; typedef long long ll; const int N=5005; int n,m,c1,c2,num,l=2e9,r=-2e9;bool vis[N];char str[N]; int b1[N],b2[N];ll s1[N],s2[N];ll ans; pair<int,int> buy[N],sell[N]; struct node{ int opt,a,b; node(int opt=0,int a=0,int b=0):opt(opt),a(a),b(b){} }da[N]; ll check(int now){ ll res1(0),res2(0); int p1=lower_bound(b1+1,b1+c1+1,now)-b1; int p2=upper_bound(b2+1,b2+c2+1,now)-b2; res1=s1[c1]-s1[p1-1];//[p1,c1] // if(b2[p2]>now) p2--;//[1,p2] res2=s2[p2-1]; // the above is faster than the below // for(int i=1;i<=c1;i++) if(buy[i].fi>=now) res1+=buy[i].se; // for(int i=1;i<=c2;i++) if(sell[i].fi<=now) res2+=sell[i].se; return min(res1,res2); } int main(){ while(gets(str)){ double a=0;int opt,b; if(str[0]=='c') opt=-1,sscanf(str,"%*s%d",&b),vis[b]=1; else{ opt=(str[0]=='b')?1:2; sscanf(str,"%*s%lf%d",&a,&b); } da[++n]=node(opt,(int)((a+1e-4)*100.0),b); //上面这个改成下面就只有90分,woc 这TMD谁知道!阴沟里翻船 // da[++n]=node(opt,(int)(a*100.0),b); } // for(int i=n;i;i--) if(da[i].opt==-1&&!vis[i]) vis[da[i].b]=1; for(int i=1;i<=n;i++){ if(~da[i].opt&&!vis[i]){ da[++m]=da[i]; } } for(int i=1;i<=m;i++){ l=min(l,da[i].a);r=max(r,da[i].a); if(da[i].opt==1) buy[++c1]=mp(da[i].a,da[i].b);else if(da[i].opt==2) sell[++c2]=mp(da[i].a,da[i].b); } sort(buy+1,buy+c1+1); sort(sell+1,sell+c2+1); for(int i=1;i<=c1;i++) b1[i]=buy[i].fi,s1[i]=s1[i-1]+buy[i].se; for(int i=1;i<=c2;i++) b2[i]=sell[i].fi,s2[i]=s2[i-1]+sell[i].se; for(int i=l;i<=r;i++){ ll res=check(i); if(ans<=res) ans=res,num=i; } printf("%.2lf %lld\n",(1.0*num)/100.0,ans); return 0; }

 

易错点

#include<iostream> using namespace std; int main(){ double a=8888.8; cout<<(int)((a+1e-4)*100.0)<<'\n';//==>888880 cout<<(int)(a*100.0)<<'\n';//==>888879 return 0; }

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/12600764.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(227)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
历史上的今天:
2017-03-30 [SCOI2010]字符串
2017-03-30 [SCOI2010]传送带[三分]
2017-03-30 [SCOI2010]序列操作[分块or线段树]
点击右上角即可分享
微信分享提示