sql實現用容量分別為5L和6L的桶量出3L的水的辦法

regonly1發表於2016-09-02

最近看到論壇裡牛蛙的一個帖子(udfrog),總結了其寫過的比較有意思的sql。

看到幾個題目也想自己玩下,看到標題這個題目覺得跟以前碰到過的用3L、5L桶量出4L水的例子有點像,就也寫了一個:

with
 tmp0 as (--容量為5L和6L的桶:
select 5 n from dual union all 
 select 6 n from dual),
 tmp1(a, b, p) as (
 select n a, n, '('||n||')' p from tmp0 union all
 select n-a, b.n, a.p || '(' || b.n || '-' || a.a || ')'  from tmp1 a, tmp0 b
  where a.a < b.n --不能出現負數的情況
   and b.n <> a.b  --每次用另一個桶
   and instr(a.p,'2')=0  --確保最短路徑
)
select a, b, p from tmp1
 where a = 3  --得到3L水

結果如下:        
A          B             P
---------- ---------- --------------------------------------------------------------------------------
         3          5   (5)(6-5)(5-1)(6-4)(5-2)
         3          6   (5)(6-5)(5-1)(6-4)(5-2)(6-3)

即:

先把5L的桶裝滿,然後倒入6L的桶(6-5),還剩1L的空間,再把5L的桶裝滿倒入6L的桶(此時桶內有5L升水,所以6L桶裝滿後5L桶就剩下4L,5-1=4),

把6L桶倒光後,再將5L桶中的4L水倒入6L桶,再把5L桶裝滿,再用5L桶把6L桶裝滿(此時6L桶有4L水,再倒入2L水就慢了,所以5L桶中還剩3L水)。

所以,最後剩下的3L水在5L桶裡面(即B欄位)。

另外一個選擇就是到6L桶裡面的做法。


推算過程有些地方沒有說明出來,比如,什麼時候水倒光,什麼時候水倒滿。不過,可以從整體數字來看出,桶是滿的還是有多少水剩餘的。

這個sql同樣適用於容量為3L、5L的桶量出4L水的例子:

         A          B P
 ---------- ---------- --------------------------------------------------------------------------------
         4          5 (3)(5-3)(3-2)(5-1)



為了更好的通用性,把目標水量也寫到前面:

with
 tmp00 as (select '4' t from dual),
 tmp0 as (
 select 3 n, t from tmp00 union all
 select 5 n, t from tmp00),
 tmp1(a, b, p, t) as (
 select n a, n, '('||n||')' p, '' t from tmp0 union all
 select n-a, b.n, a.p || '(' || b.n || '-' || a.a || ')', b.t  from tmp1 a, tmp0 b
  where a.a < b.n
    and b.n <> a.b 
    and instr(a.p,b.t)=0
 )
 select a, b, p, t from tmp1
  where a = t

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12932950/viewspace-2124390/,如需轉載,請註明出處,否則將追究法律責任。

相關文章