ITPub博客

首页 > 数据库 > Oracle > sql实现用容量分别为5L和6L的桶量出3L的水的办法

sql实现用容量分别为5L和6L的桶量出3L的水的办法

原创 Oracle 作者:regonly1 时间:2016-09-02 10:30:47 0 删除 编辑

最近看到论坛里牛蛙的一个帖子(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/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-05-10

  • 博文量
    257
  • 访问量
    1025120