问题描述
某股票交易所请你编写一个程序,根据开盘前客户提交的订单来确定某特定股票的开盘价和开盘成交量。
  该程序的输入由很多行构成,每一行为一条记录,记录可能有以下几种:
  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。

————————————————————————————————————

题目分析

严重吐槽一下,这题cancel能不能取消另一行的cancel存在很大争议。看到有博主说可以,按这个思路改怎么也取消不了。改为不能取消就100分了。CCF这种问题毫无意义。

这题拿分简单,关键是要弄懂隐含的规则,否则拿满分不易。隐含的规则就是最终输出的开盘价一定是输入的p中。为什么呢,将测试案例按p从小到大排列开,如下图所示。图示中各价格用序号标识好,方便说明。

(下述最优解意思是可以取到最大开盘价的解)

假设(8.92,9.00)区间(注意是开区间)内某一点p是最优价格,那么大于或等于这个价格的buy点有3、5,小于等于它的sell点有2,那么不管p在区间(8.92,9.00)内怎么浮动,都不影响大于它的sell点和小于它的buy点的选择,都是点2和点3、5。题目要求取最大值,所以在假设在(2,3)区间存在最优价格的情况下,取值可以无限逼近与9.00。

当价格9.00存在sell点时,值取到9.00显然不会改变原有的buy、sell点的选择。

当9.00存在sell点时,取9.00将会影响buy、sell点的选择。在趋于9.00时,设sell的总股数为a,buy的总股数为b。取到9.00时.设sell的总股数为a+c,buy的总股数为b,很容易明白min(a,b) <= min(a+c,b),即在9.00存在sell点时,得到的结果总会优于趋近于9.00却没有取9.00上的sell点的情况。推广开来,我们可以知道,假设两个点的区间(a,b]上存在最优解,那么b一定也是最优解,且b是最大的,所以b是答案。所以答案一定是存在于已知的点上 。

有人可能还会有疑问这,道题趋近于9和取就是两种截然不同的,取就的话sell就可以取点4,是不是说明有可能存在某种可能,取了点4结果不是最优的,而不取点9.00却趋近于点9.00(比如价格为8.99)价格是最优的?我们上面的证明得出以下结论:

S:两个已知点a,b构成的区间(a,b)存在最优解  B:b是最优解

在已知条件S的情况下可以推出结论B。即S -> B

但是对于S的否命题 S:两个已知点a,b构成的区间(a,b)不存在最优解。是不能得出b是最优解的。即S -> B是错误的。

所以区间(a,b)存不存在最优解和b是最优解没有直接关系,但是(a,b)存在最优解b就一定是最优解。

————————————————————————————————————————————————

算法解释

既然已知开盘价一定是输入的价格中的一个,那么将所有价格从小到大排开,循环依次检测每个价格,比较出最小的值就行。要注意的是每次判断一个价格选择时的成交价,我们不必从头到尾计算一次该价格下的成交价,这样太费时间,对于本体测试数据有以下优化算法:

  1. sum1用于计算buy买单总股数,sum2用于计算sell卖单总股数。初始化sum1为所有的buy点的和。测试数据中为625,sum1=625。sum2=0。flag=0
  2. 首先检测最小的价格8.88时,该点为buy点,标记flag为1。sum1,sum2不变。取sum1和sum2中的最小值。
  3. 到第2个点8.92时,由于flag==1,sum1减去上一个buy的值,并把flag置0,即sum1 = sum1- 175。由于该点是sell点,sum2 = sum2 + 400。比较sum1和sum2。
  4. 到到9.00时,检测到该点既有sell点也有buy点,则flag=1,sum2=sum2+1000。比较sum1,sum2。
  5. 后面重复上面步骤到经过所有点。注意,如果存在多个buy点价格一样,或者多个sell点价格一样,一定要合并相同点,即把所有的股数累加到一个点上并删除其他相同的点。否则会重复计算。
保证每个价格(不是每个点)只检测一遍,代码中我用inst表示按价格从小到大排列的所有可能选择的价格。in1所有合并同一价格的buy点,in2表示所有合并同一价格的sell点。
代码如下:
    #include <iostream>#include <vector>#include <iomanip>#include <algorithm>using namespace std;struct ins{int count;int flag;double price;long long num;int use_flag;};vector <struct ins> inst,in1,in2;bool cmp(struct ins a,struct ins b){if(a.price < b.price) {return true; } else   {return false; }}int main(){long long temp,num1=0,num2=0,flag=0;string s0;double p,PP;int i,j;long long n,sum1,sum2,SSUM=0;struct ins po;while(cin >> s0){if(s0=="buy") {cin >> p >> n;po.flag = 0;po.price = p;po.num = n;po.use_flag = 0; inst.push_back(po);}else if(s0=="sell"){cin >> p >> n;po.flag = 1;po.price = p;po.num = n;po.use_flag = 0;inst.push_back(po);}else if(s0=="cancel"){cin >> n;po.flag = 2;po.num = n;po.use_flag = 0;inst.push_back(po);}}//标记需要删除 for(i=0;i<inst.size();i++){//本来设置的是cancel可以取消另一行的cancel,结果只有50分,改为不允许取消就有100分了 if(inst[i].flag == 2 ){j = inst[i].num;inst[j-1].use_flag = 1; }}for(i=0;i<inst.size();){if(   inst[i].flag == 2 || inst[i].use_flag == 1){//删除cancel和所有被cancel删除的 inst.erase(inst.begin()+i);}else{if(inst[i].flag == 0) //将buy插入in1 {in1.push_back(inst[i]);}else{                //将sell插入in2 in2.push_back(inst[i]);}i++;}}//从小到大排序 sort(in1.begin(),in1.end(),cmp);sort(in2.begin(),in2.end(),cmp);sort(inst.begin(),inst.end(),cmp);//删除相同价格的 for(i=0;i<inst.size()-1;){if(inst[i].price == inst[i+1].price){inst.erase(inst.begin()+i);}else{i++;}}sum1 = 0;sum2 = 0;//合并相同价格的buy点 for(i=0;i<in1.size()-1;){if(in1[i].price == in1[i+1].price){in1[i].num += in1[i+1].num;in1.erase(in1.begin()+i+1);}else{i++;}}//合并相同价格的sell点 for(i=0;i<in2.size()-1;){if(in2[i].price == in2[i+1].price){in2[i].num += in2[i+1].num;in2.erase(in2.begin()+i+1);}else{i++;}}//统计所有buy点的和 for(i=0;i<in1.size();i++){sum1 += in1[i].num;}for(i=0;i<inst.size();i++){p = inst[i].price;if(flag == 1){flag = 0;sum1 = sum1 - in1[num1-1].num;}if( in1[num1].price == p ){ num1++;flag=1; }if(in2[num2].price == p){sum2 = sum2 + in2[num2++].num;  }if(sum1 > sum2){temp =  sum2;}else{temp = sum1;}if(temp >= SSUM){PP=p;SSUM=temp;}}cout << setiosflags(ios::fixed) << setprecision(2) << PP << " " << SSUM;return 0;}

CCF CSP 集合竞价 (2014-12)相关推荐

  1. 计算机能力挑战赛_蓝桥杯、PAT、CCF CSP、团体程序设计天梯赛、传智杯、计算机能力挑战赛、软考等大学生编程比赛/考试介绍...

    介绍7个适合普通大学生参加的编程比赛/考试(注:有的比赛如蓝桥杯有多种赛别,本文仅介绍其中的程序设计/编程比赛). 编程入门书籍推荐<算法笔记>,内容详细易懂,对新手非常友好,描述语言为C ...

  2. CCF CSP认证考试在线评测系统

    关于CCF CSP认证考试在线评测系统 CCF CSP认证考试简介 CCF是中国计算机学会的简称.CCF计算机软件能力认证(简称CCF CSP认证考试)是CCF于2014年推出,是CCF计算机职业资格 ...

  3. 北航ccf计算机软件能证排名前18%,CCF成功举办第十一次CCF CSP认证

    第十一次CCF CSP计算机软件能力认证(CSP)于2017年9月17日在全国66所院校举办,这是2017年度CCF举办的第二次认证,来自全国200多个单位的6591人参加了本次认证.通过对本次CSP ...

  4. CCF CSP 201609-2 火车购票

    题目链接:http://118.190.20.162/view.page?gpid=T46 问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一节车厢有20排.每一排 ...

  5. 以CCF CSP认证为抓手,积极探索软件基础能力递进式培养体系

    原文链接:以CCF CSP认证为抓手,积极探索软件基础能力递进式培养体系 发布单位:学会      发布时间:2017-01-20 16:16 作者:陆建峰    余立功 摘要:为提升计算机专业类学生 ...

  6. ccf csp寻宝!大冒险!(C语言)

    ccf csp寻宝!大冒险! 题目背景 暑假要到了.可惜由于种种原因,小 P 原本的出游计划取消.失望的小 P 只能留在西西艾弗岛上度过一个略显单调的假期--直到-- 某天,小 P 获得了一张神秘的藏 ...

  7. CCF CSP 历年试题题解

      第一题 第二题 第三题 第四题 第五题 第15次(2018.12) 小明上学 小明放学 CIDR合并 数据中心   第14次(2018.09) 卖菜 买菜 元素选择器 再卖菜   第13次(201 ...

  8. 计算机考csp200分啥水平,计算机与信息工程学院成功举办第20次CCF CSP认证考试

    2020年9月13日,计算机与信息工程学院在计算机大楼201举办第二十次CCF CSP认证考试.这是计算机与信息工程学院2019年12月与中国计算机学会签署协议.河南大学正式成为CSP认证考点以来,举 ...

  9. CCF CSP认证菜鸟刷题日志

    CCF CSP菜鸟刷题日志(c/c++) 本萌新写给自己看的,要是有大佬路过,请多多指教orz 立个flag:每日一更,至201903 9月15ccf csp,冲鸭! 今天(2019.8.18)起每天 ...

最新文章

  1. 数据分析之Pandas分组操作总结
  2. 2020全球Top10 AI专利公司:美国过半,中国仅占两席
  3. 射影几何笔记6:齐次坐标下“点-线”几何关系
  4. mt6765和骁龙665哪个好_小米11正式发布,首发骁龙888+白送快充头,售价3999起
  5. arch Linux 添加引导,ArchLinux 添加开机启动脚本, 亲测
  6. 初级开发人员的缺点_在您作为初级开发人员的第一年获得此建议
  7. 小熊的人生回忆(九)
  8. centos6和centos7防火墙的关闭
  9. mysql怎么绿化绿化_Windows下MySQL的绿化与精简
  10. 科大讯飞刘聪:如何持续保持语音识别技术的领先
  11. 如何保持格式拆分工作表?
  12. Charles最新版破解注册方法
  13. 记录deecamp2018之旅
  14. 6070. 计算字符串的数字和
  15. 个人所得税计算器(简易)
  16. CM311-1a_YST代工_安卓9_S905L3A_没无线版Emotn UI桌面线刷固件包
  17. win10开机黑屏不显示桌面,怎么办
  18. 朱清时——物理学步入禅境:缘起性空-(技术工作者上升到哲学思维)
  19. 高等数学之极限的原理及易错题计算
  20. 《东周列国志》第七十四回 囊瓦惧谤诛无极 要离贪名刺庆忌

热门文章

  1. 李威克挑战N小黑,虚拟人真实自然天花板之争的背后
  2. python匿名函数和推导式烧脑面试题解析
  3. 笔记本电脑计算机无法启动怎么办,联想笔记本开不了机怎么办 电脑开机进不了系统怎么办...
  4. 无锡计算机科学与工程学院,瞩目!公办本科,无锡学院首次招生,这些优势很突出!...
  5. 青云霍秉杰:一文读懂Prometheus长期存储主流方案
  6. 6.4 用区块链来控制风险
  7. 写一些关于如何运用计算机英语,关于介绍电脑的英语作文,80词左右.
  8. Python实现超简单【抖音】无水印视频批量下载
  9. S300V的前世今生
  10. 【十】搭建基于qemu的仿真环境与应用