程式設計之美 24點遊戲

2021-08-27 01:36:23 字數 2476 閱讀 7384

一,概述

二十四點是一種益智遊戲,它能在遊戲中鍛鍊人們的心算,它往往要求人們將四個數字進行加減乘除(允許使用括號)求得二十四。然後將四個數字的計算公式表示出來。

二,中綴表示式求解

最直接的方法就是採用窮舉法,遊戲中可用的運算子只有四種,四個數字每個只能使用一次。

1)不考慮括號情況

4個數全排列:4!=24種

需要三個運算子,且運算子可以重複:4*4*4=64

總計:1536

2)考慮括號(是個難點)

自己想的加括號:四個數有五種加括號方式: (ab)cd 、ab(cd)、a(bc)d 、a((bc)d) 、(ab)(cd)、a(b(cd))

錯誤點:這裡新增括號的時候,需要把四個數都看成相乘。需要加兩個括號來列舉比較直觀

ab(cd) = (ab)(cd)

改正後:((ab)c)d 、

(ab)(cd)、 (a(bc))d 、a((bc)d) 、a(b(cd))

四個運算數五種不同加括號方式的由來。這是乙個經典的catalan數問題。

這個經典catalan數問題在組合數學教材上都能找到。原題目是:n 個數相乘, 不改變它們的位置, 只用括號表示不同的相乘順序,令g(n)表示這種條件下構成不同乘積的方法數,令c(n)表示第n個catalan數。則有g(n)=c(n-1)。前幾個catalan數為:c(0)=1,c(1)=1,c(2)=2,c(3)=5,c(4)=14,c(5)=42。所以g(4)=c(3)=5。

根據catalan數的計算公式,有g(4)=g(1)g(3)+g(2)g(2)+g(3)g(1)。

catalan數的計算公式也同時提供了構造答案的方法。對於4個數,中間有3個位置,可以在任何乙個位置一分為二,被分開的兩半各自的加括號方案再拼湊起來就得到一種4個數的加括號方案:

乙個數時:(a),一種

兩個數:g(2)=g(1)g(1),所以是(a)(b)=(ab),一種

三個數:g(3)=g(1)g(2)+g(2)g(1)=(a)(bc)+(ab)(c),兩種

四個數:g(4)=g(1)g(3)+g(2)g(2)+g(3)g(1)

=(a)[(b)(cd)+(bc)(d)]+(ab)(cd)+[(a)(bc)+(ab)(c)](d)

=a(b(cd)) + a((bc)d) + (ab)(cd) + (a(bc))d + ((ab)c)d

共有五種。於是寫**列舉這五種加括號的方式即可。這種方法只是一種能得到正確答案的方法,擴充套件性和效率都極差。而且生成的表示式中也有冗餘括號。

#include #include using namespace std;

const double threshold = 1e-6;

const int cardsnumber = 4;

const int resultvalue = 24;

double number[cardsnumber];

string result[cardsnumber];

bool pointsgame(int n)

else

}for(int i = 0; i < n; i++)//第乙個數(計算時被兩個數結果替換)

if(a != 0)

number[i] = a;//將本次迴圈的結果消除,繼續測試下一對數

number[j] = b;

result[i] = expa;

result[j] = expb;}}

return false;

}int main()

if(pointsgame(cardsnumber))

else

}

三,分支限界法求解

#include #include #include #include using namespace std;

#define n 4 // 4張牌,可變

#define res 24 // 運算結果為24,可變

#define eps 1e-6

struct elem

elem(double r, char* i):res(r),info(i){}

double res; // 運算出的資料

string info; // 運算的過程

bool operator<(const elem& e) const };

int a[n]; // 記錄n個資料

// 用二進位制數來表示集合和子集的概念,0110表示集合包含第2,3個數

setvset[1<& fork(int m)

for (int i=1; i<=m/2; i++)

if ((i&m) == i)

if (abs(cit1->res)>eps)

}} return vset[m];

}int main()

}

程式設計之美之24點遊戲

關於程式設計之美24點遊戲的求解 思想很簡單,把array i 和array i 1 求加減乘除等運算,然後將值寫入array i 1 不難發現是乙個遞迴子過程,不難寫,如下 include include using namespace std int array string arraystr ...

程式設計之美讀書筆記22 1 16 24點遊戲

程式設計之美讀書筆記 221.1624 點遊戲給定 4個數,能否只通過加減乘除計算得到 24?由於只有 4個數,弄個多重迴圈,就可以。如果要推廣到 n個數,有兩種思路 採用字首 字尾表示式。相當於將 n個數用 n 1個括號括起來,其數目就是乙個 catlan 數。最多可得到 f n 1 n 2 n ...

程式設計之美2 4 求1的個數

推薦 從1到n的所有數中,1出現的次數 例如 f 2 1,因為就有乙個1,f 13 6,有1,10,11,12,13,1一共出現6次 include include using namespace std void fun int n ifactor 10 cout 2 擴充套件問題 同之前問題1的...