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。
解题思路:

这道题一直拿不了满分从0/30/40/50/90,心累

一道模拟题,暴力枚举,算出每个价格下的成交量取大值

我确定的价格的变化范围是卖出的最低价~买进的最高价之间,因为小于卖出的最低价或者大于买进的最高价都会使得成交量变成0,没有什么特别大的意义。

从低价格向上枚举。


注意:

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

存在一条删除命令 要删除买进或者卖出的股票
再来一条删除命令 要删除前面的删除命令/相当于前面的删除命令失效了

因为题目描述的不清楚,导致了我这样的幻觉~

去掉这部分代码之后就变成90分了。




源代码:
<span style="font-size:18px;">#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;

struct node
{
	int flag;//是否删除
	int bs;//买进还是卖出还是删除命令,1表示买进,-1表示卖出,0表示删除命令
	int price;//股票价格
	int number;//股票数量
	int index;//处于第几行命令
	int del;//要删除第几行的命令
};

node ans[5005];

void init()
{
	for(int i=0;i<5005;i++)
	{
		ans[i].flag=0;//表示不删除该命令
		ans[i].del=-1;//-1表示当前命令是b or s
		ans[i].bs=0;
	}
}

int main()
{
	char s[15];
	int k=1;//命令的位置
	int num;
	double pri;
	int order;
	init();
	while(scanf("%s",s)!=EOF)
	{
		if(s[0]=='b')//买进股票
		{
			scanf("%lf%d",&pri,&num);
			ans[k].bs=1;
			ans[k].index=k;
			ans[k].number=num;
			ans[k].price=(int)(pri*100);
			k++;
		}
		else if(s[0]=='s')//卖出股票
		{
			scanf("%lf%d",&pri,&num);
			ans[k].bs=-1;
			ans[k].index=k;
			ans[k].number=num;
			ans[k].price=(int)(pri*100);
			k++;
		}
		else if(s[0]=='c')//删除命令
		{
			scanf("%d",&order);
			ans[k].del=order;
			ans[k].index=k;
			int temp=order;
			ans[temp].flag=1;
			k++;
		}
	}
	int max_pri=0;
	int min_pri=0x3f3f3f3f;
	for(int i=1;i<k;i++)
	{
		if(ans[i].bs==1&&ans[i].flag==0)
		{
			if(ans[i].price>max_pri)
				max_pri=ans[i].price;
		}
	}
	for(int i=1;i<k;i++)
	{
		if(ans[i].bs==-1&&ans[i].flag==0)
		{
			if(ans[i].price<min_pri)
				min_pri=ans[i].price;
		}
	}
	long long ans_num=0;
	int ans_pri;
	for(int i=min_pri;i<=max_pri;i++)
	{
		long long pb=0;
		long long ps=0;
		for(int j=1;j<k;j++)
		{
			if(ans[j].bs==1&&ans[j].flag==0&&ans[j].price>=i)//买
			{
				pb+=ans[j].number;
			}
			else if(ans[j].bs==-1&&ans[j].flag==0&&ans[j].price<=i)//卖
			{
				ps+=ans[j].number;
			}
			long long temp=min(pb,ps);
			if(temp>=ans_num)
			{
				ans_pri=i;
				ans_num=temp;
			}
		}
	}
	double res_pri=(ans_pri*1.0)/100;
	printf("%.2lf %lld\n",res_pri,ans_num);
	return 0;
}</span>




posted @ 2017-11-03 01:43  lemonsbiscuit  阅读(537)  评论(0编辑  收藏  举报