ITPub博客

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

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

原创 Linux操作系统 作者:yangtingkun 时间:2008-01-02 23:45:36 0 删除 编辑

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

 

 

第一个问题:

已知两个1~30之间的数字,甲知道两数之和,乙知道两数之积。

甲问乙:"你知道是哪两个数吗?"乙说:"不知道"

乙问甲:"你知道是哪两个数吗?"甲说:"也不知道"

于是,乙说:"那我知道了"

随后甲也说:"那我也知道了"

这两个数是什么?

 

先给出SQL解,然后简单描述一下。

这道题分两种情况,两个数不重复,那么有两个可能结果:

SQL> WITH
  2  T AS
  3  (SELECT ROWNUM NUM FROM DUAL CONNECT BY LEVEL <= 30)
  4  SELECT A, B
  5  FROM
  6  (
  7   SELECT
  8    A,
  9    B,
 10    TOTAL,
 11    MUL,
 12    COUNT(*) OVER (PARTITION BY MUL) MUL_P
 13   FROM
 14   (
 15    SELECT
 16     A,
 17     B,
 18     TOTAL,
 19     MUL,
 20     COUNT(*) OVER (PARTITION BY TOTAL) TOTAL_P
 21    FROM
 22    (
 23     SELECT
 24      A.NUM A,
 25      B.NUM B,
 26      A.NUM + B.NUM TOTAL,
 27      A.NUM * B.NUM MUL,
 28      COUNT(*) OVER (PARTITION BY A.NUM * B.NUM) MUL_P
 29     FROM T A, T B
 30     WHERE A.NUM < B.NUM
 31    )
 32    WHERE MUL_P != 1
 33   )
 34   WHERE TOTAL_P != 1
 35  )
 36  WHERE MUL_P = 1
 37  ;

         A          B
---------- ----------
         1          6
         1          8

如果两个数是可以重复的,那么有唯一的答案:

SQL> WITH
  2  T AS
  3  (SELECT ROWNUM NUM FROM DUAL CONNECT BY LEVEL <= 30)
  4  SELECT A, B
  5  FROM
  6  (
  7   SELECT
  8    A,
  9    B,
 10    TOTAL,
 11    MUL,
 12    COUNT(*) OVER (PARTITION BY MUL) MUL_P
 13   FROM
 14   (
 15    SELECT
 16     A,
 17     B,
 18     TOTAL,
 19     MUL,
 20     COUNT(*) OVER (PARTITION BY TOTAL) TOTAL_P
 21    FROM
 22    (
 23     SELECT
 24      A.NUM A,
 25      B.NUM B,
 26      A.NUM + B.NUM TOTAL,
 27      A.NUM * B.NUM MUL,
 28      COUNT(*) OVER (PARTITION BY A.NUM * B.NUM) MUL_P
 29     FROM T A, T B
 30     WHERE A.NUM <= B.NUM
 31    )
 32    WHERE MUL_P != 1
 33   )
 34   WHERE TOTAL_P != 1
 35  )
 36  WHERE MUL_P = 1
 37  ;

         A          B
---------- ----------
         1          4

下面简单描述一下思路:

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

最内层的循环构造两个数的笛卡儿积,列出所有的可能,不过对于我们来说,A1B2A2B1没有区别,因此加上限制条件A > B。上面两个SQL唯一的区别就在这里,如果两个数是可以重复的那么A >= B,否则A > B

循环中的分析函数用来计算AB乘积相同的个数,如果这个数是1,说明这两个数是可以确定的。而根据乙的描述,他并不知道这两个数是什么,因此这部分应该是可以被排除的。

第二层的循环道理相同,这里排除的是A所不知道的,两个数和能确定这两个数的部分。

到了第三层,乙知道AB是什么数了,说明这个时候AB的积已经是唯一的。

 

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

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

注册时间:2007-12-29

  • 博文量
    1955
  • 访问量
    10488281