首页 > 编程语言 >UVA-1598 交易所 题解答案代码 算法竞赛入门经典第二版

UVA-1598 交易所 题解答案代码 算法竞赛入门经典第二版

时间:2023-03-07 11:01:06浏览次数:49  
标签:int 题解 price 1598 m1 UVA vmes id size


​GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版​

AC代码

有意思的一个题目。书上说这是一个不错的优先队列练习题,但实际上它其实是一个让我们了解优先队列有哪些限制的题目。

其他同学的很多题解因为优先队列限制太大,转而使用了map等结构作为优先队列的代替。我这里还是使用的优先队列。

这个题目碰到的优先队列的限制有:

1. 不能清空优先队列,无法clear

2. 不能遍历,只能查看堆顶元素

3. 默认是大顶堆,自行改变判断规则有些麻烦

因此,如果想要用优先队列做这道题,必须用到很多辅助的数据结构,比如我用到了vector,map来辅助查找。不能清空,那就只能重新赋值空队列了。

这个题目的一些注意事项:

1. 题目可能有多组数据,每组之间需要空行

2. 成交价格对当前处理的最新消息有利。比如如果新来的是买消息,那么买的价格会按照当前卖出队列的最低价格成交,而不是买消息中的价格。卖消息则使用买入队列的最高价格成交。

(所以如果我是参与交易者,我会一直出价再撤回,这样才有可能以最低价格买入,最高价格卖出)

3. 撤回消息时,如果该消息已经交易成功,那么无需任何处理。如果未成功或者已经成功了一部分,则剩下的部分被禁止交易。输出的最低最高价格中也不包含撤回的消息。

4. 如果新来的一个消息与多个队列中的消息成交,且价格相同,那么在成交的消息中,不需要合并为一条消息输出,而是分成多条输出。比如。

TRADE 200 32

TRADE 200 32

TRADE 300 32

但是在QUOTE消息中,同价格的却需要合并到一条输出。

#include<iostream>
#include<string>
#include<queue>
#include<map>
using namespace std;

struct MES {
int id;
int size;
int price;
int bs;
bool operator< (const MES &rhs) const {
if(this->price != rhs.price) {
return this->price < rhs.price;
}
return this->id > rhs.id;
}
bool operator> (const MES &rhs) const {
if(this->price != rhs.price) {
return this->price > rhs.price;
}
return this->id > rhs.id;
}
};

vector<MES> vmes;
priority_queue<MES, vector<MES>, less<MES>> buys;
priority_queue<MES, vector<MES>, greater<MES>> sells;
map<int, int> mpBuy, mpSell;

void deleteMes(int id) {
if(id >= vmes.size() || !vmes[id].size) {
return;
}
if(vmes[id].bs > 0) {
mpBuy[vmes[id].price] -= vmes[id].size;
} else {
mpSell[vmes[id].price] -= vmes[id].size;
}
vmes[id].size = 0;
}

void buyMes(MES &m) {
MES m1, m2;
int size, price;
while(!sells.empty() && m.size) {
m1 = sells.top();
if(vmes[m1.id].size == 0) {
sells.pop();
continue;
}
if(vmes[m1.id].price > m.price) {
break;
}
price = vmes[m1.id].price;
if(m.size >= vmes[m1.id].size) {
size = vmes[m1.id].size;
sells.pop();
} else {
size = m.size;
}
mpSell[price] -= size;
m.size -= size;
vmes[m1.id].size -= size;
cout << "TRADE " << size << " " << price << endl;
}
}

void sellMes(MES &m) {
MES m1, m2;
int size, price;
while(!buys.empty() && m.size) {
m1 = buys.top();
if(vmes[m1.id].size == 0) {
buys.pop();
continue;
}
if(vmes[m1.id].price < m.price) {
break;
}
price = vmes[m1.id].price;
if(m.size >= vmes[m1.id].size) {
size = vmes[m1.id].size;
buys.pop();
} else {
size = m.size;
}
mpBuy[price] -= size;
m.size -= size;
vmes[m1.id].size -= size;
cout << "TRADE " << size << " " << price << endl;
}
}

int main() {
int n, i, j, k;
int id;
string s;
MES m1, m2;
int size, price;
bool flag = false;
while(cin >> n && n != 0) {
if(flag == false) {
flag = true;
} else {
cout << endl;
}
priority_queue<MES, vector<MES>, less<MES>> buysT;
priority_queue<MES, vector<MES>, greater<MES>> sellsT;
buys = buysT;
sells = sellsT;
mpBuy.clear();
mpSell.clear();
vmes.clear();
for(i = 0; i < n; ++i) {
MES m;
m.id = i;
cin >> s;
if(s == "CANCEL") {
cin >> id;
id = id - 1;
deleteMes(id);
m.price = 0;
m.size = 0;
} else {
cin >> m.size >> m.price;
if (s == "BUY") {
m.bs = 1;
buyMes(m);
if(m.size > 0) {
if(!mpBuy.count(m.price)) {
mpBuy[m.price] = 0;
}
mpBuy[m.price] += m.size;
buys.push(m);
}
} else { //sell
m.bs = -1;
sellMes(m);
if(m.size > 0) {
if(!mpSell.count(m.price)) {
mpSell[m.price] = 0;
}
mpSell[m.price] += m.size;
sells.push(m);
}
}
}
vmes.push_back(m);
cout << "QUOTE ";
size = 0; price = 0;
while(!buys.empty()) {
m1 = buys.top();
if(vmes[m1.id].size == 0) {
buys.pop();
continue;
}
price = vmes[m1.id].price;
size = mpBuy[vmes[m1.id].price];
break;
}
cout << size << " " << price;
cout << " - ";
size = 0; price = 99999;
while(!sells.empty()) {
m1 = sells.top();
if(vmes[m1.id].size == 0) {
sells.pop();
continue;
}
price = vmes[m1.id].price;
size = mpSell[vmes[m1.id].price];
break;
}
cout << size << " " << price;
cout << endl;
}
}
return 0;
}

标签:int,题解,price,1598,m1,UVA,vmes,id,size
From: https://blog.51cto.com/u_15995687/6105511

相关文章

  • PAT 乙级 1014 题解 (Basic Level) Practice
    很简单的一道题,我的程序有点乱#include<stdio.h>#include<string.h>#include<ctype.h>intmain(){chars1[61];chars2[61];chars3[61];chars4[61];s......
  • [CF1648D]Serious Business 题解
    [CF1648D]SeriousBusiness题解首先容易想到一个\(dp\)转移式子:\[dp_{i}=\max_{j\lei}s_{1,j}-cost_{j,i}-s_{2,j-1}+s_{2,i}+s_{3,n}-s_{3,i-1}\]其中\(dp_i\)......
  • NOI2023春测题解
    NOI2023春测题解目录NOI2023春测题解更好的阅读体验戳此进入游记戳此进入T1LG-P9117[春季测试2023]涂色游戏题面SolutionCodeT2LG-P9118[春季测试2023]幂次题面So......
  • 春季测试2023全题解
    T1涂色游戏非常困难的题目,我们需要记录每一行/每一列最后一次被修改的时间以及被修改成什么颜色。输出的时候每一个格子是受行影响还是列影响即可。复杂度\(O(nm)\)。......
  • [SDOI2019] 移动金币 题解
    首先考虑一个状态什么时候是合法的。不难把游戏过程抽象为阶梯Nim博弈。根据阶梯Nim博弈的结论,先手必胜当且仅当奇数位上的异或和不为0。考虑将本题中每个棋子后面......
  • AcWing 4490. 染色题解
    题目描述样例输入:612215211111输出3算法描述思路我们以样例为例讲讲思路。如何确保dfs能顺利便利呢,我们可以使用链式前向星来存图(树)C++代......
  • AcWing 4495. 数组操作题解
    思路此题较为简单,简述一下思路。从小到大排序,每次选取最小值,只要不为0即可每次都为序列减去一个数字太慢,但每个数又减去的数字一样,所以可以用minus记录每个数要减去的数......
  • 3.2 L5-NOIP训练29 测试题解
    3.2L5-NOIP训练29测试题解码创Contest#530(出题人写中文也要句句都打分号吗!!)A.老司机的压缩包(数论)题面老司机最近得到了一个奇怪的压缩包,听说里面有十分厉害的东西......
  • 3 月 1 日测试题解
    3月1日测试题解T1题意给你一个\(n\timesm\)的01矩形,求一个面积最大的不包含数字1的矩形。\(n,m\le1000\)。思路首先,这道题的数据水到了什么程度呢?\(O(n......
  • MySQL Workbench 8.0 点击Server Status面板Could not acquire management access for
    转载自:MySQLWorkbench8.0点击ServerStatus面板Couldnotacquiremanagementaccessforadministration报错问题解决Win10安装MySQLWorkbench8.0后连接MySQL服务......