https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_PRoblem&problem=1544
有三个水杯,容量分别为 a, b, c 刚开始 c 水杯注满水,其他是空的,然后求经过 n 次操作后可不可以得到 d 升水。如果可以的话,转移的水量尽量少,如果无法得到 d 升的话,就输出 d’ 升,d’< d 并且 d’ 尽量的大。
这里的转移水量指,总共转移了多少升水,比如 a 向 b 注了五升水,那么转移水量为五升。
照着紫书示例敲得,看作者代码学到了好多东西。
首先是进行枚举操作的时候,虽然总共三个杯子,作者还是把数据放到了数组里面,简化不少代码,如果是我的话,就直接写9个if了。
然后是代码的思想是 dijkstra,求最短路。
把整个问题当做一个状态图,每个点由三个水杯里面的水确定。两个点之间的边的权值,是由两个状态转化所需要转移的水量。(注意一点是这里是有向图)另外三个水杯里面的水合不变,给定两个水杯里水的体积,就可以确定另一个,所以储存状态时,只需要记录两个水杯的体积即可。经过上面的解析,这个问题就抽象成了,求一个有向图的最短路径,然后使用了优先队列优化的 dijkstra 。
另外memcpy的使用值得一学,使用方法如下: memset(&a, &b, sizeof(a));
把 b 复制给a,直接复制的内存,效率比直接循环快。
新闻热点
疑难解答