ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 用SQL解决两道有趣的题(二)

用SQL解决两道有趣的题(二)

原创 Linux操作系统 作者:yangtingkun 时间:2008-01-03 09:47:25 0 删除 编辑

Oracle的SQL语句功能还是很强的,看到两道比较有趣的题,用SQL来尝试求解。

用SQL解决两道有趣的题(一):http://yangtingkun.itpub.net/post/468/448940

 

 

第二个问题:

Gauss和Poincare在天堂相遇了,上帝说:你们都是人间最伟大的数学家,那我来出道题考考你们谁更聪明。我在左手写一个大于1小于100的数,在右手同样写一个大于1小于100的数,然后把他们的和写在Gauss手上,把积写在Poincare手上,看看你们能不能猜出这两个数字是几。
Gauss
看了手上的数字,说:“我不知道这两个数字是几,可我保证Poincare也不知道。”
Poincare
看了手上的数字,说:“我原来的确不知道那两个数字是几,可我现在知道了。
”
Gauss
说:“那我也知道了。
”
问题:那两个数字是几?

粗看上去似乎和刚才第一题很像,如果仔细研究就会发现二者的区别还是很大的,相比之下,这道题比第一题要难一些。

仍然是先给出SQL解,然后描述一下思路:

SQL> WITH T_NUM AS
  2  (SELECT ROWNUM + 1 NUM FROM DUAL CONNECT BY LEVEL < 99)
  3  SELECT A, B
  4  FROM
  5  (
  6   SELECT
  7    A,
  8    B,
  9    TOTAL,
 10    MUL,
 11    MUL_P,
 12    COUNT(DECODE(MUL_P, 1, 1)) OVER(PARTITION BY TOTAL) VALUE
 13   FROM
 14   (
 15    SELECT
 16     A,
 17     B,
 18     TOTAL,
 19     MUL,
 20     COUNT(*) OVER (PARTITION BY TOTAL) TOTAL_P,
 21     COUNT(*) OVER (PARTITION BY MUL) MUL_P
 22    FROM
 23    (
 24     SELECT
 25      A,
 26      B,
 27      TOTAL,
 28      MUL,
 29      MIN(MUL_P) OVER (PARTITION BY TOTAL) MUL_M
 30     FROM
 31     (
 32      SELECT
 33       A.NUM A,
 34       B.NUM B,
 35       A.NUM + B.NUM TOTAL,
 36       A.NUM * B.NUM MUL,
 37       COUNT(*) OVER (PARTITION BY A.NUM + B.NUM) TOTAL_P,
 38       COUNT(*) OVER (PARTITION BY A.NUM * B.NUM) MUL_P 
 39      FROM T_NUM A, T_NUM B
 40      WHERE A.NUM < B.NUM
 41     )
 42    ) 
 43    WHERE MUL_M != 1
 44   )
 45  )
 46  WHERE MUL_P = 1
 47  AND VALUE = 1;

         A          B
---------- ----------
         4         13

下面简单描述一下思路:

WITH语句就是构造一张基础数据表。

最内层的循环构造两个数的笛卡儿积,列出所有的可能,不过对于我们来说,A取1,B取2和A取2,B取1没有区别,因此加上限制条件A > B。循环中的分析函数用来计算A、B两个数的和相同的个数以及A、B两个数的积相同的个数。

下面到了这道题和第一题的区别之处。Gauss不但自己不知道,还可以确认Poincare也不知道。这说明A、B两个数构成Gauss手里的和TATOL不但不是唯一的,而且所有能构成这个TOTAL的A和B的积MUL都不是唯一的。这就是第二层嵌套的含义。

到了第三层,过滤掉上面那些不符合条件的A和B之后。要解决的问题就是Poincare知道A和B的答案后,Gauss也知道了。

这说明对于TOTAL这个值,所有A和B的组合中有一个且只有一个组合它们的乘积是唯一确定的。这是通过第四层嵌套中那个COUNT(DECODE) OVER实现的。

最后过滤乘积唯一,且对于相同TOTAL的所有A和B组合中有且仅有一个乘积唯一确定的A、B组合。

如果还是不明白,可以将这个嵌套一层层执行,观察每一步的执行结果,有助于理解每一步实现的目的。

 

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

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1964
  • 访问量
    11076243