Problem description:
4 cards for players, each with a face value of 1 ~ 13. Use +,-, *,/, and brackets to set the final result to 24.
Answer:
1. Exhaustion
Each number can only be used once, so a total of 4 numbers are arranged in full! = 24 sorting;
Three Four-Rule operator numbers are required: 4 ^ 3 = 64;
(A (B (CD), (A (BC) D), (AB) (CD), (a (BC) d), (AB) c) d) 5
Total: 4! * 4 ^ 3*5 = 7680 types;
2. Divide and conquer Law
Assume that the Set A = {1, 2, 3, 4} is first randomly taken out, such as removing 1, 2, A = A-{1, 2} and performing different arithmetic operations, 1 + 2 = 3, 1-2 =-1, 1*2 = 2, 1/2 = 0.5. Add the result to set a respectively. You can obtain the following information:
B = {3, 3, 4}, c = {-1, 3}, 4}, D = {2, 3, 4}, E = {0.5, 3, 4} four new collections:
All possible values of set a f (a) = F (B) + f (c) + f (d) + f (e) are reduced from four to three.
Pseudocode:
F (array) {If (array. length <2) {If (the final result is 24) Output expression; else cannot construct} for each (any combination of two numbers from the array) {for each (operator (+, -, *,/) {1. calculate the result of the combination under this operator; 2. remove the two numbers from the original array and add the result of step 1 to the array; 3. recursively call F for the new array. If an expression is found, return. 4. remove the result from step 1 and put the two numbers in the combination back into the array ;}}}
3. Branch Limit Method
Ren ran assumes that set a, first adopt the sub-governance idea, divide set a into A1 and A-A1, respectively for the two of them four arithmetic to solve F (A1) and F (A-A1 ), finally, perform four arithmetic operations on the elements in the two sets. The Union of all the sets obtained is f ()
The element operation in defining two sets A and B is as follows:
Fork (a, B) = {A + B, A-B. B-a, a * B, A/B (B! = 0), B/A (! = 0 )}
Use a four-digit binary number to represent the true subset of set:
1111: {A0, A1, 12, A3}, 1110: {A1, A2, A3 }......
Initialize 0001,0010, 0100,1000 as a condition for Recursive termination.
1111 = {1110,0001} U ......
Use the array s [I] To save the set f (I)
The final result s [2n-1] is all the results of all the elements of set a through the four arithmetic operations. Check s [2n-1] to obtain the result.
The following is an implementation:
#include <iostream>#include <map>#include <vector>#include <set>using namespace std;int N,m;map<int,set<int>> S;set<int>& f(int i){if (!S[i].empty())return S[i];for (int x=1; x<=i/2; x++){if( (x&i) == x){set<int>&s1 = f(i-x);set<int>&s2 = f(x);for(set<int>::iterator it1=s1.begin(); it1!=s1.end(); it1++)for(set<int>::iterator it2=s2.begin(); it2!=s2.end(); it2++){S[i].insert(*it1 + *it2);S[i].insert(*it1 - *it2);S[i].insert(*it1 - *it2);S[i].insert(*it1 * *it2);if(*it2!=0) S[i].insert(*it1 / *it2);if(*it1!=0) S[i].insert(*it2 / *it1);}}}return S[i];}int main(){int a[4];N=4;int i;for(i=0; i<N;i++) {cin>>a[i];S[1<<i].insert(a[i]);}int num = (1<<N) - 1;f(num);int c = S[num].count(24);cout<<"count: "<<c<<endl;}
This is a dish I wrote. It can only be output or not. I think it's easy to read from other online experts. I recommend the following. Here, you can take a look at the opposite of this article ~
# Include <iostream> # include <set> # include <string> # include <cmath> using namespace STD; # define N4 // four cards, variable # define res24 // The operation result is 24. Variable # define EPS 1e-6struct ELEM {ELEM (Double R, string & I): res (R), Info (I) {} ELEM (Double R, char * I): res (R), Info (I) {} double res; // the calculated data string Info; // bool operator <(const ELEM & E) const {return res <E. res; // The comparison operation must be used in the insert operation of the Set red/black tree}; int A [n]; // record n pieces of data // the concept of a set and a subset is expressed in binary., 0110 indicates that the set contains the second and second sets <ELEM> vset [1 <n]; // a set containing four elements has 16 subsets 0-15 set <ELEM> & fork (INT m) {// memo recursive if (vset [M]. size () {return vset [m] ;}for (INT I = 1; I <= m/2; I ++) // calculate fork (I) separately) and fork (m-I), So If (I & M) = I) {set <ELEM> & S1 = fork (I ); set <ELEM> & S2 = fork (M-I); // obtain the Cartesian product of two subsets, perform six operations on the element pairs in the result set for (set <ELEM >:: iterator cit1 = s1.begin (); cit1! = S1.end (); cit1 ++) for (set <ELEM >:: iterator cit2 = s2.begin (); cit2! = S2.end (); cit2 ++) {string STR; STR = "(" + cit1-> info + "+" + cit2-> info + ")"; vset [M]. insert (ELEM (cit1-> res + cit2-> res, STR); STR = "(" + cit1-> info + "-" + cit2-> info + ") "; vset [M]. insert (ELEM (cit1-> res-cit2-> res, STR); STR = "(" + cit2-> info + "-" + cit1-> info + ") "; vset [M]. insert (ELEM (cit2-> res-cit1-> res, STR); STR = "(" + cit1-> info + "*" + cit2-> info + ")"; vset [M]. insert (ELEM (cit1-> res * cit2-> res, STR); If (ABS (cit2-> res)> EPS) {s Tr = "(" + cit1-> info + "/" + cit2-> info + ")"; vset [M]. insert (ELEM (cit1-> Res/cit2-> res, STR);} If (ABS (cit1-> res)> EPS) {STR = "(" + cit2-> info + "/" + cit1-> info + ")"; vset [M]. insert (ELEM (cit2-> Res/cit1-> res, STR) ;}}return vset [m]; // do not forget this step} int main () {int I; for (I = 0; I <n; I ++) CIN> A [I]; // recursion end condition; for (I = 0; I <n; I ++) {char STR [10]; sprintf (STR, "% d", a [I]); vset [1 <I]. insert (ELEM (A [I], STR);} fork (1 <n)-1); // start 1111 It indicates four numbers. // The 24-point calculation process is displayed. For (set <ELEM >:: iterator it = vset [(1 <n)-1]. begin (); it! = Vset [(1 <n)-1]. end (); It ++) {If (ABS (IT-> res-res) <EPS) cout <it-> info <Endl ;}}