【习题 5-14 UVA

【链接】 我是链接,点我呀:)
【题意】

在这里输入题意

【题解】

各组数据之间有空行! 且最后一行后面没有空行! 然后就是用set来模拟就好。 删除的时候,不着急删除。 因为并不用时刻输出集合大小。所以只要遇到了把它删掉就Ok. 把相同的合并那里。我直接暴力合并了。 因为 150 30 100 30 不能看出一个整体的250 30的。。 要分步输出Trade信息的. 然后在合并的时候也要注意看里面有没有已经删除了的。 已经删除了的就直接跳过。。

【代码】

#include <bits/stdc++.h>
using namespace std;

const int N = 1e4;

struct abc {
	int num, price;

	abc(int x = 0, int y = 0) :num(x), price(y) {}
};

abc re[N + 10];

struct setcmp1
{
	bool operator () (const int &a, const int &b)
	{
		if (re[a].price == re[b].price)
			return a < b;
		else
			return re[a].price > re[b].price;
	}
};
struct setcmp2
{
	bool operator () (const int &a, const int &b)
	{
		if (re[a].price == re[b].price)
			return a < b;
		else
			return re[a].price < re[b].price;
	}
};

set <int, setcmp1> buyset;//买的价格,越大越好
set <int, setcmp2> sellset;//卖的价格,越小越好
bool dele[N + 10];//用来记录某个交易是否被删除了。并不用时刻输出集合大小。所以只要遇到了把它删掉就Ok
int n;

void cl()
{
	bool shan1, shan2;
	do
	{
		shan1 = shan2 = false;
		while (buyset.size() > 1 && dele[*buyset.begin()]) buyset.erase(buyset.begin()), shan1 = true;
		while (sellset.size() > 1 && dele[*sellset.begin()]) sellset.erase(sellset.begin()), shan2 = true;
	} while (shan1 || shan2);
}

void out()
{
	int num1 = 0, num2 = 0;
	int price1 = re[*buyset.begin()].price, price2 = re[*sellset.begin()].price;
	for (auto it : buyset)
		if (re[it].price == price1)
		{
			if (!dele[it]) num1 += re[it].num;
		}
		else break;
	for (auto it : sellset)
		if (re[it].price == price2)
		{
			if (!dele[it]) num2 += re[it].num;
		}
		else break;
	printf("QUOTE %d %d - %d %d
", num1, price1, num2, price2);
}

int main()
{
	//freopen("F:\rush.txt", "r", stdin);
	int kk = 0;
	while (~scanf("%d", &n))
	{
		if (kk > 0) puts("");
		kk++;
		re[N + 1].num = 0, re[N + 1].price = 0;
		re[N + 2].num = 0, re[N + 2].price = 99999;
		memset(dele, 0, sizeof dele);
		buyset.clear(); sellset.clear();
		buyset.insert(N + 1); sellset.insert(N + 2);
		for (int i = 1; i <= n; i++)
		{
			char s[10];
			scanf("%s", s);
			switch (s[0])
			{
			case ('C'):
			{
				int x;
				scanf("%d", &x);
				dele[x] = true;
				cl();//看看队首是不是要删掉 
				out();
				break;
			}
			case ('B'):
			{//买进
				int num, price;
				scanf("%d%d", &num, &price);
				while (sellset.size() > 1 && num >0 && price >= re[*sellset.begin()].price)
				{
					int temp = min(re[*sellset.begin()].num, num), temp2 = re[*sellset.begin()].price;
					num -= temp;
					re[*sellset.begin()].num -= temp;
					if (re[*sellset.begin()].num == 0)
					{
						sellset.erase(sellset.begin());
						cl();
					}
					printf("TRADE %d %d
", temp, temp2);
				}
				re[i] = abc(num, price);
				if (num != 0) buyset.insert(i);
				out();
				break;
			}
			case 'S':
			{
				//卖
				int num, price;
				scanf("%d%d", &num, &price);
				while (buyset.size() > 1 && num >0 && price <= re[*buyset.begin()].price)
				{
					int temp = min(re[*buyset.begin()].num, num), temp2 = re[*buyset.begin()].price;
					num -= temp;
					re[*buyset.begin()].num -= temp;
					if (re[*buyset.begin()].num == 0)
					{
						buyset.erase(buyset.begin());
						cl();
					}
					printf("TRADE %d %d
", temp, temp2);
				}
				re[i] = abc(num, price);
				if (num != 0) sellset.insert(i);
				out();
				break;
			}
			default:
				break;
			}
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7686073.html