您的位置:首页 > 编程语言

编程之美-24点游戏源码

2010-08-22 17:22 375 查看
方法1.深搜

/*
<编程之美>
深搜
遍历运算符, 数和括号的所有排列形式
*/
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
const  double Threshold = 1e-6;
const int CardsNumber = 4;
const int ResultValue = 24;
double number[CardsNumber];
string result[CardsNumber];

bool PointGame(int n)
{
if(n == 1)
{
if(fabs(number[0] - ResultValue) < Threshold)
{
cout << result[0] << endl;
return true;
}
else
{
return false;
}
}

for(int i = 0; i < n; i++)
{
for(int j = i +1 ; j < n; j++)
{
double a, b;
string expa, expb;

a = number[i];
b = number[j];
number[j] = number[n - 1];

expa = result[i];
expb = result[j];
result[j] = result[n-1];

//+加法操作 a+b
number[i] = a + b;
result[i] = '(' + expa + '+' + expb + ')';
if(PointGame(n-1))
{
return true;
}

//减法操作 a-b
number[i] = a - b;
result[i] = '(' + expa + '-' + expb + ')';
if(PointGame(n-1))
{
return true;
}

//减法操作 b-a
number[i] = b - a;
result[i] = '(' + expb + '-' + expa + ')';
if(PointGame(n-1))
{
return true;
}

//乘法操作 a*b
number[i] = a * b;
result[i] = '(' + expa + '*' + expb + ')';
if(PointGame(n-1))
{
return true;
}

//除法操作 a/b, 如果除数不为0
if(b != 0)
{
number[i] = a / b;
result[i] = '(' + expa + '/' + expb + ')';
if(PointGame(n-1))
{
return true;
}
}

//除法操作 b/a , 如果除数不为0
if(a != 0)
{
number[i] = b / a;
result[i] = '(' + expb + '/' + expa + ')';
if(PointGame(n-1))
{
return true;
}
}

number[i] = a;
number[j] = b;
result[i] = expa;
result[j] = expb;

}
}
return false;

}

int main()
{
int x;
for(int i =0; i< CardsNumber; i++)
{
cout << "the " << i << "the number: ";
cin >> x;
number[i] = x;
result[i] = (char)(x + '0');
}

if(PointGame(CardsNumber))
{
cout << "Success" << endl;

}
else
{
cout << "failure" << endl;
}
system("pause");
return 0;
}


方法二,记忆化搜索

/*
编程之美方法2
记忆化搜索
*/
#include <iostream>
#include <string>
#include <set>
#include <math.h>
using namespace std;
const  double Threshold = 1e-6;
const int CardsNumber = 4;
const double ReslutNumber = 24;
const int ExCardsNumber = (1 << CardsNumber);
int number[CardsNumber];

//在集合中存储的元素
struct node
{
double value; //值
string exp;//对应的表达式
node()
{
}
node(double v, string e)
{
value = v;
exp = e;
}
};
struct cmp
{
bool operator()(const node a, const node b)
{
if(a.value != b.value) return a.value > b.value;
else return a.exp > b.exp;
}
};
set<node, cmp> S[16];
//主要递归函数
void getSandResult(int i)
{
if(!S[i].empty()) return;

set<node>::iterator iterda, iterdb;
node a, b;

for(int x = 1; x < i; x ++)
{
if((x & i) == x)              //注意==的优先级要比&的优先级大
{

//事先调用下面这两个函数确保在计算S[i]之前S[x]与X[i-x]已经计算出来
getSandResult(x);
getSandResult(i - x);

//之后遍历S[x],S[i-x]两个集合,将计算出来的结果存储入S[i]中
for(iterda = S[x].begin(); iterda != S[x].end(); iterda ++)
{
for(iterdb = S[i-x].begin(); iterdb != S[i-x].end(); iterdb ++)
{
a = *iterda, b = *iterdb;

S[i].insert(node(a.value + b.value, '(' + a.exp + '-' + b.exp + ')'));

S[i].insert(node(a.value - b.value, '(' + a.exp + '-' + b.exp + ')'));
S[i].insert(node(b.value - a.value, '(' + b.exp + '-' + a.exp + ')'));

S[i].insert(node(a.value * b.value, '(' + a.exp + '*' + b.exp + ')'));

if(b.value != 0)
{
S[i].insert(node(a.value / b.value, '(' + a.exp + '/' + b.exp + ')'));
}

if(a.value != 0)
{
S[i].insert(node(b.value / a.value, '(' + b.exp + '/' + a.exp + ')'));
}

}//end for
}//end for

}//end if
}//end for
}
//相当于一个外壳,用来包裹递归,
void Game24()
{
//初始化S[i]
for(int i = 0; i< ExCardsNumber; i++)
{        S[i].clear();
}
char buffer[10];
for(int i = 0; i< CardsNumber; i++)
{

buffer[0] = (char)('0' + number[i]);
buffer[1] = 0;
S[1 << i].insert(node(number[i], string(buffer)));
}

//调用下面递归计算出 S[15]的集合
getSandResult(ExcardsNumber - 1);

//遍历S[15],取出想要的结果
set<node>::iterator iterd;
for(iterd = S[ExCardsNumber -1].begin(); iterd != S[ExCardsNumber -1].end(); iterd ++)
{
if(fabs((*iterd).value - ReslutNumber) < Threshold)
{
cout << (*iterd).exp << endl;
}
}
}
int main()
{

for(int i = 0; i < CardsNumber; i++)
{
cin >> number[i];
}

Game24();

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: