ITPub博客

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

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

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

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

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

 

 

第二个问题:

GaussPoincare在天堂相遇了,上帝说:你们都是人间最伟大的数学家,那我来出道题考考你们谁更聪明。我在左手写一个大于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语句就是构造一张基础数据表。

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

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

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

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

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

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

 

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

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

注册时间:2007-12-29

  • 博文量
    1955
  • 访问量
    10456575