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,直接復制的內存,效率比直接循環快。
新聞熱點
疑難解答