UVa 1598 Exchange 翻译+解题

来源:互联网 发布:浪腾软件 编辑:程序博客网 时间:2024/06/05 10:08

这个题目巨长,而紫书上的描述巨简单,但是看了题目的样例之后,心中mmp,这踏马什么玩意,怎么输出还能是这样。看了原题的输入输出细节之后,只想说,这哪跟哪啊,啥都看不懂。这下只能看原题了。(英语还没过四级,,因为还没考,,,,翻译的烂请谅解)

第一段就不翻译了,因为没啥信息。

这个有一个订货簿啊(后面就用本子代替了啊),它记录着一些订单,还有取消订单的记录啥的。这种没有被取消的订单被称为 active(这个词还是不翻译,后面用的挺多),其中就有buy 和sell这两种订单(买卖用多了就分不清了,还是写成英语吧),这两种订单都由数量和价格两部分组成。本子上面有一系列的active订单,还有一些 quote 和 trade 订单(哈,都不翻译,不翻译比翻译过来好,我觉得)。active订单中buy方的出价最高价格的就叫 bid 价格。sell方出价最低的价格称为 ask 价格。ask 价格总是低于bid 价格。也就是说,buy 方总是希望 sell 方给出的价格能低些。(其实都是些废话啦)

一个 quote 包含 bid 数量 , bid 价格,ask 数量和 ask 价格。这里的 bid 和 ask 的数量指的是所有订单中和 bid 和 ask 价格一样订单数量的总和。(这是重点啦)

一个 trade 记录着这个 buy 方和 sell 方进行的这个交易。其中就有 数量和价格 这两个内容。

如果这时突然新增了一个 buy 订单,并且出价和当前的 ask 价格相等或者是高一些。这是相应的订单就会相匹配,然后就会发生一个 trade ,在这时,buy 方会和 sell 方找到一个合适的价格成交,反之亦然。如果新增一个 sell 订单,并且出价和当前 bid 价格相等或者是低一些。这个 trade 也会发生。为了满足这个订单匹配的要求,本子就像一个先进先出的队列一样去管理这些价格相同的订单。想深入了解请往下看。

当新增一个 buy 订单时,并且出价和当前的 ask 价格相等或者是高一些。这时不会马上在本子上记录它,首先会产生一系列的 trade ,可能会减少 buy 的数量。trade 以当前ask 价格生成,交易的数量就是两个匹配订单中数量的较小者。两个匹配订单的数量都减少了 trade 的数量。如果,sell 订单中的数量减少到0,那么这个订单就变成变成 非active 的了(非active,哈哈,通俗易懂是吧)。既然不是active 订单了,本子就不记录它了。如果这时的 buy 方还没达到所需要的数量。这时另一个 sell 方就会和它匹配,该过程将继续以新的 ask 价格进一步交易,如果本子上没有 sell 方愿意与其匹配。则这个 buy 订单就会加入到本子中,数量为其剩余的数量。

如果新增的是 sell 订单,则与上面的类似,它会与 buy 方相匹配,trade按照 bid 价格生成。

在收到取消请求时,相应的订单将从本子中简单地删除,并变为非active。请注意,在取消请求时,相应订单的数量可能已经部分减少或订单可能已停用。取消非active订单的请求不会更改本子中的任何内容。

在每一个传入的消息中,本子必须在处理相应的消息之后产生它所造成的所有交易和当前quote(bid 数量,bid 价格,ask 数量,ask 价格),即使订单中没有任何变化也是如此

终于翻译完了。。。。。。。。你们懂了没

现在干正事,解题吧。
翻译完了,卧草。。。。我有种被耍了的感觉,作者是要考验我英语阅读理解水平么。今天又相当于做了一篇阅读理解,照这个情况下去,四级是真的不用愁了。。。。。。

解题:https://github.com/morris821028/UVa/blob/master/temp/1598%20-%20Exchange.cpp 这个程序就写的十分好。值得学习一下。

下面是我的思路,TLE了……希望有大神指出来我的程序的问题

解题,过程简直了。我之前想到的是用优先队列(紫书上也写了啊),写出来后找了udebug上的数据测试,通过测试数据了,然后我提交。。结果TLE了,哎,我又回去改了改,提交还是TLE,后来我就去网上找了这个题目的解法,发现他们用的居然都是map,没用queue。我把他们的程序复制下来,我用udebug上的数据测试了,又加个显示运行的时间语句,网上找到的程序运行时间一般都在1.3s左右,后来在github上找到一个0.6s的,然后我测了一下我的:0.5s!!!!我擦。0.5s都超时了那些1.3s的怎么AC的,况且udebug上的测试数据也差不多有1万多个(或者还多),而题目要求n小于10000,我这完全没问题啊。我想了想是不是某个特殊数据导致程序进入死循环了,我到现在都没搞懂是为什么,我讲一下我的程序的大概(希望有大佬看到了能指出来我的问题):

我定义了两个优先队列,一个叫BUY,另一个叫SELL,还定义了一个长度为10000的bool数组。就是下面这样子:

struct goods { int id, num, pri; };const int maxn = 10000+10;bool cancel[maxn];priority_queue<goods, vector<goods>, cmp1> buy; //按照价格从高到底priority_queue<goods, vector<goods>, cmp2> sell; //按照价格从低到高vector<goods> save1, save2;

每次收到一个cancel n指令,我就令cancel[n] = true; 标记一下。后处理
每次我们接收一个BUY或者是SELL单,我们都需要判断当前是否能够交易,怎么判断呢? 我先把程序接收的订单先存入buy(或者是sell),在判断之前我们还要做一个操作,将分别将队列buy和队列sell中前几个价格相同的元素取出来按顺序分别存入save1和save2中,然后再进行判断,若save1中的元素的价格高于或者是等于save2中的元素的价格,我们让save1和save2中的元素按顺序来做减法,若其中某个元素的数量减为0,我们就让它的下一个元素继续做减法,直到其中一个vector中没有元素了,然后将另一个vector中剩余的元素一一入队。然后循环上面那个过程,直到save1中的元素的价格低于save2中的元素的价格或者是buy、sell队列其中一个为空。(大概就是上面那样,希望能有大佬能帮帮我~~orz,大佬可以私信我,或者回复这篇博客都行,谢谢了)