设为首页 收藏本站
查看: 1150|回复: 0

[经验分享] [刷题]算法竞赛入门经典(第2版) 5-14/UVa1598

[复制链接]

尚未签到

发表于 2017-7-1 23:26:51 | 显示全部楼层 |阅读模式
  题意:模拟买卖,当出售价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_VAL 和 SELL_VAL),而当时我只用了两个map(BUY和SELL)存买卖的所有信息,所以每次查询循环总的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,还是有些出乎意料。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-390232-1-1.html 上篇帖子: rabbitmq级联之shovel插件和exchange.bind 下篇帖子: Java多线程——其他工具类CyclicBarrier、CountDownLatch和Exchange
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表