小浩演算法|一文讓你學會如何用程式碼判斷"24"點

宜信技術學院發表於2020-02-26

“24點”是一種數學遊戲,正如象棋、圍棋一樣是一種人們喜聞樂見的娛樂活動。它始於何年何月已無從考究,但它以自己獨具的數學魅力和豐富的內涵正逐漸被越來越多的人們所接受。今天就為大家分享一道關於“24點”的演算法題目。

話不多說,直接看題。

題目:你有 4 張寫有 1 到 9 數字的牌。你需要判斷是否能通過 *,/,+,-,(,) 的運算得到 24。

示例 1:

輸入: [4, 1, 8, 7]

輸出: True

解釋: (8-4) * (7-1) = 24

示例 2:

輸入: [1, 2, 1, 2]

輸出: False

注意:

  • 除法運算子 / 表示實數除法,而不是整數除法。例如 :4 / (1 - 2/3) = 12 。
  • 每個運算子對兩個數進行運算。特別是我們不能用 - 作為一元運算子。例如,[1, 1, 1, 1] 作為輸入時,表示式 -1 - 1 - 1 - 1 是不允許的。
  • 你不能將數字連線在一起。例如,輸入為 [1, 2, 1, 2] 時,不能寫成 12 + 12 。

題目分析

拿到題目,第一反應就可以想到暴力求解。如果我們要判斷給出的4張牌是否可以通過組合得到24,那我們只需找出所有的可組合的方式進行遍歷。

4個數字,3個操作符,外加括號,基本目測就能想到組合數不會大到超出邊界。所以,我們只要把他們統統列出來,不就可以進行求解了嗎?說幹就幹!

我們首先定義個方法,用來判斷兩個數的的所有操作符組合是否可以得到24。

func judgePoint24_2(a, b float64) bool {
    return a+b == 24 || a*b == 24 || a-b == 24 || b-a == 24 || a/b == 24 || b/a == 24 
}

但是這個方法寫的正確嗎?其實不對!因為在計算機中,實數在計算和儲存過程中會有一些微小的誤差,對於一些與零作比較的語句來說,有時會因誤差而導致原本是等於零但結果卻小於或大於零之類的情況發生,所以常用一個很小的數 1e-6 代替 0,進行判讀!

(1e-6:表示1乘以10的負6次方。Math.abs(x)<1e-6 其實相當於x==0。1e-6(也就是0.000001)叫做epslon,用來抵消浮點運算中因為誤差造成的相等無法判斷的情況。這個知識點需要掌握!)

舉個例子:

func main() {
    var a float64
    var b float64
    b = 2.0
    //math.Sqrt:開平方根
    c := math.Sqrt(2)
    a = b - c*c
    fmt.Println(a == 0)                  //false
    fmt.Println(a < 1e-6 && a > -(1e-6)) //true
}

這裡直接用 a==0 就會得到false,但是通過 a < 1e-6 && a > -(1e-6) 卻可以進行準確的判斷。

所以我們將上面的方法改寫:

 //go語言
 //judgePoint24_2:判斷兩個數的所有操作符組合是否可以得到24
 func judgePoint24_2(a, b float64) bool {
     return (a+b < 24+1e-6 && a+b > 24-1e-6) ||
         (a*b < 24+1e-6 && a*b > 24-1e-6) ||
         (a-b < 24+1e-6 && a-b > 24-1e-6) ||
         (b-a < 24+1e-6 && b-a > 24-1e-6) ||
         (a/b < 24+1e-6 && a/b > 24-1e-6) ||
         (b/a < 24+1e-6 && b/a > 24-1e-6) 
}

完善了通過兩個數來判斷是否可以得到24的方法,現在我們加一個判斷三個數是否可以得到24的方法。

//硬核程式碼,不服來辯!
func judgePoint24_3(a, b, c float64) bool {
    return judgePoint24_2(a+b, c) ||
        judgePoint24_2(a-b, c) ||
        judgePoint24_2(a*b, c) ||
        judgePoint24_2(a/b, c) ||
        judgePoint24_2(b-a, c) ||
        judgePoint24_2(b/a, c) ||
 
        judgePoint24_2(a+c, b) ||
        judgePoint24_2(a-c, b) ||
        judgePoint24_2(a*c, b) ||
        judgePoint24_2(a/c, b) ||
        judgePoint24_2(c-a, b) ||
        judgePoint24_2(c/a, b) ||
        judgePoint24_2(c+b, a) ||
        judgePoint24_2(c-b, a) ||
        judgePoint24_2(c*b, a) ||
        judgePoint24_2(c/b, a) ||
        judgePoint24_2(b-c, a) ||
        judgePoint24_2(b/c, a)
}

好了。三個數的也出來了,我們再加一個判斷4個數為24點的方法:(排列組合,我想大家都會....)

前方高能!!!

前方高能!!!

前方高能!!!

//硬核程式碼,不服來辯!
func judgePoint24(nums []int) bool {
    return judgePoint24_3(float64(nums[0])+float64(nums[1]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])-float64(nums[1]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])*float64(nums[1]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])/float64(nums[1]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])-float64(nums[0]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])/float64(nums[0]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])+float64(nums[2]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])-float64(nums[2]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])*float64(nums[2]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])/float64(nums[2]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[2])-float64(nums[0]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[2])/float64(nums[0]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])+float64(nums[3]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[0])-float64(nums[3]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[0])*float64(nums[3]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[0])/float64(nums[3]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[3])-float64(nums[0]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[3])/float64(nums[0]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[2])+float64(nums[3]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[2])-float64(nums[3]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[2])*float64(nums[3]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[2])/float64(nums[3]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[3])-float64(nums[2]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[3])/float64(nums[2]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[1])+float64(nums[2]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])-float64(nums[2]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])*float64(nums[2]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])/float64(nums[2]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[2])-float64(nums[1]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[2])/float64(nums[1]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])+float64(nums[3]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[1])-float64(nums[3]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[1])*float64(nums[3]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[1])/float64(nums[3]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[3])-float64(nums[1]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[3])/float64(nums[1]), float64(nums[2]), float64(nums[0]))
}

Go語言示例

搞定收工,我們整合全部程式碼如下:

//硬核程式設計...
func judgePoint24(nums []int) bool {
    return judgePoint24_3(float64(nums[0])+float64(nums[1]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])-float64(nums[1]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])*float64(nums[1]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])/float64(nums[1]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])-float64(nums[0]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])/float64(nums[0]), float64(nums[2]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])+float64(nums[2]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])-float64(nums[2]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])*float64(nums[2]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])/float64(nums[2]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[2])-float64(nums[0]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[2])/float64(nums[0]), float64(nums[1]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[0])+float64(nums[3]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[0])-float64(nums[3]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[0])*float64(nums[3]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[0])/float64(nums[3]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[3])-float64(nums[0]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[3])/float64(nums[0]), float64(nums[2]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[2])+float64(nums[3]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[2])-float64(nums[3]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[2])*float64(nums[3]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[2])/float64(nums[3]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[3])-float64(nums[2]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[3])/float64(nums[2]), float64(nums[0]), float64(nums[1])) ||
        judgePoint24_3(float64(nums[1])+float64(nums[2]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])-float64(nums[2]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])*float64(nums[2]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])/float64(nums[2]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[2])-float64(nums[1]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[2])/float64(nums[1]), float64(nums[0]), float64(nums[3])) ||
        judgePoint24_3(float64(nums[1])+float64(nums[3]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[1])-float64(nums[3]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[1])*float64(nums[3]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[1])/float64(nums[3]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[3])-float64(nums[1]), float64(nums[2]), float64(nums[0])) ||
        judgePoint24_3(float64(nums[3])/float64(nums[1]), float64(nums[2]), float64(nums[0]))
}
func judgePoint24_3(a, b, c float64) bool {
    return judgePoint24_2(a+b, c) ||
        judgePoint24_2(a-b, c) ||
        judgePoint24_2(a*b, c) ||
        judgePoint24_2(a/b, c) ||
        judgePoint24_2(b-a, c) ||
        judgePoint24_2(b/a, c) ||
        judgePoint24_2(a+c, b) ||
        judgePoint24_2(a-c, b) ||
        judgePoint24_2(a*c, b) ||
        judgePoint24_2(a/c, b) ||
        judgePoint24_2(c-a, b) ||
        judgePoint24_2(c/a, b) ||
        judgePoint24_2(c+b, a) ||
        judgePoint24_2(c-b, a) ||
        judgePoint24_2(c*b, a) ||
        judgePoint24_2(c/b, a) ||
        judgePoint24_2(b-c, a) ||
        judgePoint24_2(b/c, a)
}
func judgePoint24_2(a, b float64) bool {
    return (a+b < 24+1e-6 && a+b > 24-1e-6) ||
        (a*b < 24+1e-6 && a*b > 24-1e-6) ||
        (a-b < 24+1e-6 && a-b > 24-1e-6) ||
        (b-a < 24+1e-6 && b-a > 24-1e-6) ||
        (a/b < 24+1e-6 && a/b > 24-1e-6) ||
        (b/a < 24+1e-6 && b/a > 24-1e-6)
}

由於程式碼過於硬核,

我們直接擊敗100%的對手:

(沒想到吧!程式碼還可以這麼寫~)

本期的題目應該都能看懂嗎?

大家還有其他的方法來得到答案嗎?

評論區留下你的想法吧!

來源:宜信技術學院

小浩:宜信科技中心攻城獅一枚,熱愛演算法,熱愛學習,不拘泥於枯燥程式設計程式碼,更喜歡用輕鬆方式把問題簡單闡述,希望喜歡的小夥伴可以多多關注!

原文首發於:「小浩演算法」


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69918724/viewspace-2677241/,如需轉載,請註明出處,否則將追究法律責任。

相關文章