四人过桥问题的SQL解法

看了开发版的帖子,又没有忍住,简单写了一个SQL语句。关于问题的详细描述可以参考http://www.itpub.net/thread-1595264-1-1.html

 

 

传说中的微软面试题:

有一群人A,B,C,D (人数>=2)要在夜里走过独木桥过河,他们只有一把手电筒。四个人的速度不同,过河分别需要1,2,5,10分钟,桥上最多走两个人,两个人一起走时按速度慢的计算。过河一定要用手电筒。请问最快的方法是如何安排,需要几分钟?

例子输出:

A B,A,A C,A,A D  19

直接给出最终结果:

SQL> WITH C AS
  2  (SELECT NAME, TIME, POWER(2, ROWNUM - 1) POS FROM BRIDGE_CROSSING),
  3  A AS
  4  (SELECT 0 RN, A.NAME || ' ' || B.NAME NAME, GREATEST(A.TIME, B.TIME) TIME, A.POS + B.POS POS
  5  FROM C A, C B
  6  WHERE A.NAME < B.NAME
  7  UNION ALL
  8  SELECT 1, NAME, TIME, POS FROM C),
  9  B (RN, NAME, TIME, POS) AS
 10  (SELECT 0 RN, CAST ('' AS VARCHAR2(4000)) NAME, 0, 0 POS FROM DUAL
 11  UNION ALL
 12  SELECT B.RN + 1,
 13     B.NAME || ',' || A.NAME,
 14     B.TIME + A.TIME,
 15     DECODE(MOD(B.RN, 2), 0, B.POS + A.POS, B.POS - A.POS)
 16  FROM B, A
 17  WHERE MOD(B.RN, 2) = A.RN
 18  AND DECODE(MOD(B.RN, 2), 0, BITAND(B.POS, A.POS), BITAND(B.POS - A.POS, A.POS)) = 0)
 19  SELECT LTRIM(NAME, ',') NAME, TIME FROM
 20  (SELECT NAME, TIME, RANK() OVER(ORDER BY TIME) RN
 21  FROM B
 22  WHERE POS = POWER(2, 4) - 1)
 23  WHERE RN = 1;

NAME                                 TIME
------------------------------ ----------
A B,A,C D,B,A B                        17
A B,B,C D,A,A B                        17

简单描述一下思路,通过构造一个POS列标识每个人的位置,比如1101表明ABD三个人都已经过桥了,如果POS的值达到15,则说明所有人都过桥。

这个递归WITH和以往的区别在于,两个人一起过桥和一个人回来送手电的处理规则是不同的,甚至连接数据都是不同的。这里采用将两个人过桥和一个人回来作为不同的记录插入到同一个表中,然后用不同的ID进行区别。随后的递归调用,无论是查询列,还是进行关联的时候都要进行条件的判断,判断当前是两个人过桥,还是一个人回来,从而进行不同的操作。

 

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-721858/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/4227/viewspace-721858/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值