解法二
用数字i代表集合,比如i=15,表示成二进制位1111,代表a1,a2,a3,a4均在集合中
(x&i)==x则x为i子集
因为若x&i==x 则x与i的二进制表示中x为1的位i必为1,x为0的位,i可为0或1,又x<i所以x为0的位i不可能全为1,所以x为i的真子集
代码参考了
http://blog.csdn.net/suwei19870312/article/details/5830373
#include<iostream>
#include<string>
#include<math.h>
#include<vector>
using namespace std;
const int CardsNumber = 4;
const double ResultValue=24;
const int PowCardsNumber = (1 << CardsNumber);
const double Threshold=1E-6;
class node;
vector<node> s[16];
int number[CardsNumber];
class node{
public:
node(){}
node(double v,string s):value(v),exp(s){}
double value;
string exp;
};
void fork(int i){
node a,b;
//若已有值,则直接返回
if(!s[i].empty())return;
for(int x=1;x<i;x++){
//&运算,若相等,说明x是i的子集
if((x&i)==x){
fork(x);
fork(i-x);
vector<node>::iterator itera,iterb;
for(itera=s[x].begin();itera!=s[x].end();itera++){
for(iterb=s[i-x].begin();iterb!=s[i-x].end();iterb++){
a=*itera;
b=*iterb;
s[i].push_back(node(a.value+b.value,'('+a.exp+'+'+
b.exp+')'));
s[i].push_back(node(a.value-b.value,'('+a.exp+'-'+
b.exp+')'));
s[i].push_back(node(b.value-a.value,'('+b.exp+'+'+
a.exp+')'));
s[i].push_back(node(a.value*b.value,'('+a.exp+'*'+
b.exp+')'));
if(b.value!=0)
s[i].push_back(node(a.value/b.value,'('+a.exp+'/'+
b.exp+')'));
if(a.value!=0)
s[i].push_back(node(b.value/a.value,'('+b.exp+'/'+
a.exp+')'));
}
}
}
}
}
void Game(){
node a;
for(int i=1;i<PowCardsNumber;i++)
s[i].clear();
char buf[10];
//初始化集合中只有一张牌的情形
//可能的四则混合运算值为该卡片的值本身
for(int i=0;i<CardsNumber;i++){
sprintf(buf, "%d", number[i]);
string str = buf;
s[1<<i].push_back(node(number[i],str));
}
fork(15);
vector<node>::iterator iter;
for(iter=s[PowCardsNumber-1].begin();
iter!=s[PowCardsNumber-1].end();iter++){
a=*iter;
if(fabs(a.value-ResultValue)<Threshold){
cout<<a.exp<<endl;
}
}
cout<<"can not find a case for 24 Game"<<endl;
}
int main(){
while(true){
cout<<"please enter 4 numbers for 24 point game"<<endl;
for(int i=0;i<CardsNumber;i++)
cin>>number[i];
Game();
}
return 0;
}