用SQL解決兩道有趣的題(一)

yangtingkun發表於2008-01-02

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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章