题意:模拟买卖,当出售价bid等于或低于出售价ask,则交易。


代码:(Accepted,0.330s)

//UVa1598 - Exchange
//Accepted 0.330s
//#define _XIENAOBAN_
#include<functional>
#include<algorithm>
#include<iostream>
#include<utility>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std; struct INFO { char type; int size, price; }for_push_back;
int N, T(0);
char type[20];
vector<INFO> LIST; //key: buy/ask id, value: type, size
map<int, set<int>, greater<int> > BUY; //key: bid price, value: id
map<int, set<int>, less<int> > SELL; //key: ask price, value: id
map<int, int> BUY_VAL; //key: bid price, value: size
map<int, int> SELL_VAL; //key: ask price, value: size inline int sum(set<int>& now) {
int re(0);
for (const auto& r : now) re += LIST[r].size;
return re;
} void trade(bool flag) {
int bid_size, bid_price, ask_size, ask_price;
while (true) {
auto bid(BUY.begin()), ask(SELL.begin());
if (bid == BUY.end()) bid_size = 0, bid_price = 0;
else bid_size = BUY_VAL[bid->first], bid_price = bid->first;
if (ask == SELL.end()) ask_size = 0, ask_price = 999999;
else ask_size = SELL_VAL[ask->first], ask_price = ask->first;
if (bid_price < ask_price) {
printf("QUOTE %d %d - %d %d\n", bid_size, bid_price, ask_size, (ask_price == 999999 ? 99999 : ask_price));
return;
}
auto sizeb(LIST[*bid->second.begin()].size), sizea(LIST[*ask->second.begin()].size);
const auto mini(min(sizeb, sizea));
printf("TRADE %d %d\n", mini, flag ? ask_price : bid_price); auto& b(bid->second), &a(ask->second);
BUY_VAL[bid->first] -= mini;
if (!b.empty() && (LIST[*b.begin()].size -= mini) == 0)
b.erase(b.begin());
if (b.empty()) BUY.erase(bid);
SELL_VAL[ask->first] -= mini;
if (!a.empty() && (LIST[*a.begin()].size -= mini) == 0)
a.erase(a.begin());
if (a.empty()) SELL.erase(ask);
}
} int main()
{
#ifdef _XIENAOBAN_
#define gets(T) gets_s(T, 66666)
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif while (scanf("%d", &N) != EOF) {
if (T++) puts("");
LIST.clear(), BUY.clear(), SELL.clear(), BUY_VAL.clear(), SELL_VAL.clear();
LIST.push_back(for_push_back);
for (int n(1);n <= N;++n) {
INFO tmp;
scanf("%s", type);
if (*type == 'C') {
int id;
scanf("%d", &id);
auto& csl(LIST[id]);
if (csl.type == 'B') {
BUY_VAL[csl.price] -= csl.size;
LIST[id].size = 0;
auto& now(BUY[csl.price]);
now.erase(id);
if (now.empty()) BUY.erase(csl.price);
}
else {
SELL_VAL[csl.price] -= csl.size;
LIST[id].size = 0;
auto& now(SELL[csl.price]);
now.erase(id);
if (now.empty()) SELL.erase(csl.price);
}
}
else {
tmp.type = *type;
scanf("%d%d", &tmp.size, &tmp.price);
if (*type == 'B') BUY[tmp.price].insert(n), BUY_VAL[tmp.price] += tmp.size;
else SELL[tmp.price].insert(n), SELL_VAL[tmp.price] += tmp.size;
}
LIST.push_back(std::move(tmp));
trade(*type == 'B');
}
}
return 0;
}

分析:书上推荐使用优先队列,然而并没有想出来怎么去用。想了想还是用了map,用它的begin(),效果一样的,还可以灵活差入数据。一开始老是在某组测试数据上出现Runtime error,搞得生无可恋。(从一老司机学到的新技能:当提交OJ出现RE时(WA也行),在执行每组数据计算的代码末尾加一句“while(1);”再提交如果从RE变成TLE了则说明是某些特殊数据没照顾到。毕竟不是所有OJ都有udebug可以用,这招还是不错的)

然后过了一天还是心里放不下,又回来想了想,是题目中一个细节“If there is no active order to sell, then it is assumed that ask size is zero and ask price is 99 999. Note, that zero is not a legal price, but 99 999 is a legal price. Recipient of quote messages distinguishes actual 99 999 ask price from the special case of absent orders to sell by looking at its ask size.”出了问题。于是把不可交易价格改成999999,与交易最大价格加以99999区分,果然似乎没问题了。然而接下来就有新问题,Time limit exceeded。。。

又过了一天,心里还是放不下,于是去网上查了查别人的代码,他们不仅用两个map存买卖信息,还再单独开辟两个map来存放sell与buy的总size(就相当于我上面那两个BUY_VALSELL_VAL),而当时我只用了两个map(BUYSELL)存买卖的所有信息,所以每次查询循环总的size时要经历一个比较烦的循环,就是以下这个循环:

//求当前价格总的size函数
int sum(set<int>& now) {
int re(0);
for (const auto& r : now) re += LIST[r].size;
return re;
}
//trade函数片段
auto bid(BUY.begin()), ask(SELL.begin());
if (bid == BUY.end()) bid_size = 0, bid_price = 0;
else bid_size = sum(bid->second), bid_price = bid->first;
if (ask == SELL.end()) ask_size = 0, ask_price = 999999;
else ask_size = sum(ask->second), ask_price = ask->first;

这就是超时的罪魁祸首。改进了下瞬间变成0.330s,还是有些出乎意料。

[刷题]算法竞赛入门经典(第2版) 5-14/UVa1598 - Exchange的更多相关文章

  1. [刷题]算法竞赛入门经典(第2版) 5-4/UVa10763 - Foreign Exchange

    题意:有若干交换生.若干学校,有人希望从A校到B校,有的想从B到C.C到A等等等等.如果有人想从A到B也刚好有人想从B到A,那么可以交换(不允许一对多.多对一).看作后如果有人找不到人交换,那么整个交 ...

  2. [刷题]算法竞赛入门经典(第2版) 4-6/UVa508 - Morse Mismatches

    书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,10 ms) //UVa508 - Morse Mismatches #include< ...

  3. [刷题]算法竞赛入门经典(第2版) 5-15/UVa12333 - Revenge of Fibonacci

    题意:在前100000个Fibonacci(以下简称F)数字里,能否在这100000个F里找出以某些数字作为开头的F.要求找出下标最小的.没找到输出-1. 代码:(Accepted,0.250s) / ...

  4. [刷题]算法竞赛入门经典(第2版) 5-13/UVa822 - Queue and A

    题意:模拟客服MM,一共有N种话题,每个客服MM支持处理其中的i个(i < N),处理的话题还有优先级.为了简化流程方便出题,设每个话题都是每隔m分钟来咨询一次.现知道每个话题前来咨询的时间.间 ...

  5. [刷题]算法竞赛入门经典(第2版) 4-5/UVa1590 - IP Networks

    书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) //UVa1590 - IP Networks #include<iost ...

  6. [刷题]算法竞赛入门经典(第2版) 6-7/UVa804 - Petri Net Simulation

    题意:模拟Petri网的执行.虽然没听说过Petri网,但是题目描述的很清晰. 代码:(Accepted,0.210s) //UVa804 - Petri Net Simulation //Accep ...

  7. [刷题]算法竞赛入门经典(第2版) 6-6/UVa12166 - Equilibrium Mobile

    题意:二叉树代表使得平衡天平,修改最少值使之平衡. 代码:(Accepted,0.030s) //UVa12166 - Equilibrium Mobile //Accepted 0.030s //# ...

  8. [刷题]算法竞赛入门经典(第2版) 6-1/UVa673 6-2/UVa712 6-3/UVa536

    这三题比较简单,只放代码了. 题目:6-1 UVa673 - Parentheses Balance //UVa673 - Parentheses Balance //Accepted 0.000s ...

  9. [刷题]算法竞赛入门经典(第2版) 5-16/UVa212 - Use of Hospital Facilities

    题意:模拟患者做手术. 其条件为:医院有Nop个手术室.准备手术室要Mop分钟,另有Nre个恢复用的床.准备每张床要Mre分钟,早上Ts点整医院开张,从手术室手术完毕转移到回复床要Mtr分钟.现在医院 ...

  10. [刷题]算法竞赛入门经典(第2版) 5-11/UVa12504 - Updating a Dictionary

    题意:对比新老字典的区别:内容多了.少了还是修改了. 代码:(Accepted,0.000s) //UVa12504 - Updating a Dictionary //#define _XieNao ...

随机推荐

  1. pyqt样式表语法笔记(上) --原创

    pyqt样式表语法笔记(上) pyqt QSS python 样式表 因为软件课设的原因开始学习使用pyqt4,才发现原来它也有样式表,而且语法跟css基本相同,而且一些功能实现起来感觉比js要简单方 ...

  2. SVG动画实践篇-模拟音量高低效果

    git 地址:https://github.com/rainnaZR/svg-animations/tree/master/src/demo/step2/volumn 说明 这个动画的效果就是多个线条 ...

  3. Linux开机启动(bootstrap)上

    Linux开机启动(bootstrap)   作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 计算机开机是一个神秘的过程.我们只是 ...

  4. poj 2369 Permutations (置换入门)

    题意:给你一堆无序的数列p,求k,使得p^k=p 思路:利用置换的性质,先找出所有的循环,然后循环中元素的个数的lcm就是答案 代码: #include <cstdio> #include ...

  5. Unity编译Android的原理解析和apk打包分析

    作者介绍:张坤 最近由于想在Scene的脚本组件中,调用Android的Activity的相关接口,就需要弄明白Scene和Activity的实际对应关系,并对Unity调用Android的部分原理进 ...

  6. 理解C++中的头文件和源文件的作用【转】

    一.C++编译模式通常,在一个C++程序中,只包含两类文件--.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C+ ...

  7. jdk1.8新特性,还不知道的朋友还不看看,1.9都快出来了

    一.接口的默认方法 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,示例如下:代码如下:interface Formula {     ...

  8. PHPCMS笔记第二弹

    熟练地使用PHPCMS可以插入模板,将静态站转变为动态站也更加方便,多加练习还是有好处的 将index.html的头和尾拆分出来,分别放在header.html和footer.html文件夹中,这三个 ...

  9. 用MPLAB IDE编程时,软件总是弹出一个窗口提示: “the extended cpu mode configuration bit is enabled,but the program that was loaded was not built using extended cpu instructions. therefore,your code may not work properly

    用MPLAB IDE编程时,软件总是弹出一个窗口提示:"the extended cpu mode configuration bit is enabled,but the program ...

  10. 事件驱动的简明讲解(python实现)

    关键词:编程范式,事件驱动,回调函数,观察者模式 作者:码匠信龙 举个简单的例子: 有些人喜欢的某个公众号,然后去关注这个公众号,哪天这个公众号发布了篇新的文章,没多久订阅者就会在微信里收到这个公众号 ...