UVA 1598 Exchange

这道题目难在阅读,翻译如下(第一段可以省略,从第二段开始)

       订货薄会接收到一系列的消息,这些消息是订单或者是取消之前订单的请求。没有被取消的订单是激活状态的。订单类型分为购买订单和销售订单。每一个购买订单或者是销售订单有两个正数的变量size和price。订货薄保持了一系列激活状态的订单列表,并且产生quote(报价)和trades(交易)。激活状态的购买订单中价格最高的是最优购买订单,相应的价格称为投标价格,贩卖订单中最低价格是最优的贩卖订单,相应的价格被称为沽盘价格。注意:沽盘价格(ask price)总是会低于投标价格(bid price)。

订货薄中的当前报价中,包含了当前的投标量、投标价格、沽盘量、沽盘价格,其中投标量对应着相应的投标价格的激活状态的订单的总量,沽盘量对应着相应沽盘价格的激活状态订单的总量。

交易包含了卖家和买家的交易信息,每一个交易拥有大小和价格信息。

如果订货薄接收到了购买的订单,并且该订单的价格大于等于当前的沽盘价格,那么相应的两个订单就会匹配,并且交易就会发生——买家和卖家就会在价格上达成一致。反之亦然,如果订货薄接收到了卖家的订单,并且该订单的价格小于等于当前的投标价格,交易同样会发生。出于匹配订单的目的,订货薄对于同样价格的处理将会表现出先进先出队列的性质(后面会详细介绍)

当订货薄接收到了购买订单,并且该订单的价格大于等于当前的沽盘价格,该购买订单并不会立即被录入到订货薄,首先,一系列的交易会产生,减少该订单所订物品的容量信息。交易会在到来的购买订单以及最优的贩卖订单之间产生。如果有多个最优订单(指贩卖订单),那么会选择这些订单中第一个进入到订货薄的订单。对于发生交易的购买订单和贩卖订单中,交易的数量将会是这两个订单中的数量的最小值。同时两个订单原有的数量都会同样的减少。如果贩卖订单中的物品数量减少为零,那么它就会变为非激活状态,并且从订货薄中移除。如果到来的购买订单的物品数量减小为零,那么这个过程就结束——到来的这个订单就会变为非激活状态。如果到来订单的数量仍然为正并且有另外的贩卖订单进行匹配,那么上述的过程就会继续进行,在新的沽盘价格(随着新的贩卖订单被取出队列,沽盘价格可能会变化)下进行下一步的交易。如果没有新的贩卖订单进行匹配(当前的沽盘价格比到来的购买订单的投标价格要高),那么到来的够买订单就会被存入到订货薄,注意:购买订单中的物品数量肯能会改变(因为之前已经出现的交易)。

对于到来的贩卖订单,过程将会和上述相似——它将会和订货薄中的购买订单匹配,并且交易将会根据投标价格产生。

对于到来的取消请求,相应的订单将会从订货薄中移除,并且被移除的订单将会成为非激活状态。注意,在取消请求到来的时候,应该被取消的订单中的物品数量可能已经部分的减少了或者该订单可能已经变为非激活状态了。取消请求仅仅影响当前订单的物品容量,不影响已经减少的物品容量,同时,对于非激活状态的订单的取消请求没有任何影响。

对于每一个到来的订单,订货薄必须产生该订单所产生的所有的交易,并且在处理每一个到来的信息之后也要产生一个当前的报价(quote)信息(投标量 投标价格 沽盘量 沽盘价格)。即便对于到来的订单对订货薄没有产生任何改变的前提下。因此,订货薄产生的报价消息的数量总是等于到来的信息的数量的。

输入

输入将会包含几个测试数据。相邻的测试数据之间将会以一个空行间隔。

输入的第一行包含了一个整数值n(1<=n<=10000)——订货薄需要处理的信息数量。紧随的n行包含了订单信息。每一行以一个描述订单类型的单词开头——"BUY","SELL","CANCEL",后面跟着一系列的消息参数。

"BUY","SELL"分别对应着购买和贩卖的订单,后面跟着两个整数q和p(1<=p,q<=99999)——数量和规模。"CANCEL"代表着取消先前的订单,它后面跟着一个整数i,i代表着信息的编号。(信息的编号从1到n)

输出

对于每一个测试数据,连续的测试数据之间要以一个空行分隔。

输出一系列的报价(quote)以及交易(trade)信息,对于每一个交易信息,以“TRADE”开头,后面跟着空格以及交易量和交易价格。对每一个报价,以“QUOTE”开头,后面跟着空格、投标量、投标价格、减号(-)沽盘量和沽盘价格(所有的这些都要以空格分隔)。

特殊情况:当没有激活状态的购买订单或者贩卖订单,那么就进行如下处理:如果没有激活状态的购买订单,那么就记为投标数量和投标价格为0,如果没有激活状态的贩卖订单,那么就记为沽盘数量为0沽盘价格为99999。

更多细节大家可以关注题目中给出的示例。

题目的求解见注释,利用两个map来对优先队列就进行模拟就行了。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

map> Buy;//映射:购买价格到购买的指令编号
map Buy_total;//映射:购买价格到购买总量
map> Sell;//映射:卖的价格到卖的指令编号
map Sell_total;//映射:贩卖价格到贩卖总量
typedef struct command{
	string com;
	int price, amount;
	int id;
}command;

vector Com;//存储指令

void Deal(int flag){//处理"TRADE"
	while (!Buy.empty()&&!Sell.empty()){
		if (Buy.rbegin()->first>=Sell.begin()->first){
			set& v1 = Buy.rbegin()->second;
			set& v2 = Sell.begin()->second;
			int number1 = *v1.begin();
			int number2 = *v2.begin();
			int size = min(Com[number1].amount,Com[number2].amount);
			Com[number1].amount -= size;
			Com[number2].amount -= size;
			Buy_total[Com[number1].price] -= size;
			Sell_total[Com[number2].price] -= size;
			cout << "TRADE " << size << " " << (flag ? Com[number1].price : Com[number2].price)<second<<  " " <<  Buy_total.rbegin()->first << " - ";
	}
	if (Sell_total.size() == 0) cout << "0 99999" << endl;
	else cout <second << " " << Sell_total.begin()->first <<  endl;
}

int main(){
	int Case = 0;
	int n;
	while (cin >> n){
		Buy.clear();  Buy_total.clear();
		Sell.clear(); Sell_total.clear();
		Com.clear();
		if (Case++) cout << endl;
		for (int i = 0; i < n; i++){
			command temp;
			cin >> temp.com;
			if (temp.com == "BUY"){
				cin >> temp.amount >> temp.price;
				Buy[temp.price].insert(i);
				Buy_total[temp.price] += temp.amount;
				Com.push_back(temp);
				Deal(0);
			}
			else if (temp.com=="SELL"){
				cin >> temp.amount >> temp.price;
				Sell[temp.price].insert(i);
				Sell_total[temp.price] += temp.amount;
				Com.push_back(temp);
				Deal(1);
			}
			else{
				int id;
				cin >> id;
				id--;
				temp.id = id;
				Com.push_back(temp);
				int price = Com[id].price;
				if (Com[id].com == "BUY"){
					Buy[price].erase(id);
					Buy_total[price] -= Com[id].amount;
					if (Buy[price].empty()) Buy.erase(price);
					if (Buy_total[price] == 0) Buy_total.erase(price);
					Com[id].amount = 0;
				}
				if(Com[id].com=="SELL"){
					Sell[price].erase(id);
					Sell_total[price] -= Com[id].amount;
					if (Sell[price].empty()) Sell.erase(price);
					if (Sell_total[price] == 0) Sell_total.erase(price);
					Com[id].amount = 0;
				}
			}
			Print();
		}
	}
	return 0;
}



你可能感兴趣的:(Uva,oj)