编程之美-----24点游戏
来源:互联网 发布:三维建模软件 编辑:程序博客网 时间:2024/05/05 08:06
编程之美-----24点游戏
问题:
给玩家4张牌,每张牌的面值在1-13之间,允许其中有数值相同的牌,采用加、减、乘、除四则运算,允许中间运算存在小数,并且可以使用括号,但每张牌只能用一次。构造表达式,使其结果为24.
解法一:具体见书分析,这里利用了枚举,通过递归解法.
- #include <iostream>
- #include <cmath>
- 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)
- {
- if(n == 1)
- {
- // 由于浮点数运算会有精度误差,所以用一个很小的数1E-6来做容差值
- // 本书2.6节中讨论了如何将浮点数转化为分数的问题
- if(fabs(number[0] - ResultValue) < Threshold)//结果等于24
- {
- 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];//表达式去除
- result[i] = '(' + expa + '+' + expb + ')';
- number[i] = a + b;//去除第一个数
- if(PointsGame(n - 1))
- return true;
- result[i] = '(' + expa + '-' + expb + ')';
- number[i] = a - b;
- if(PointsGame(n - 1))
- return true;
- result[i] = '(' + expb + '-' + expa + ')';
- number[i] = b - a;
- if(PointsGame(n - 1))
- return true;
- result[i] = '(' + expa + '*' + expb + ')';
- number[i] = a * b;
- if(PointsGame(n - 1))
- return true;
- if(b != 0)
- {
- result[i] = '(' + expa + '/' + expb + ')';
- number[i] = a / b;
- if(PointsGame(n - 1))
- return true;
- }
- if(a != 0)
- {
- result[i] = '(' + expb + '/' + expa + ')';
- number[i] = b / a;
- if(PointsGame(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++)
- {
- char buffer[20];
- cout << "the " << i << "th number:";
- cin >> x;
- number[i] = x;
- itoa(x, buffer, 10);
- result[i] = buffer;
- }
- if(PointsGame(CardsNumber))
- {
- cout << "Success." << endl;
- }
- else
- {
- cout << "Fail." << endl;
- }
- }
- #include <iostream>
- #include <set>
- #include <string>
- #include <cmath>
- using namespace std;
- #define N 4 // 4张牌,可变
- #define RES 24 // 运算结果为24,可变
- #define EPS 1e-6
- struct Elem
- {
- Elem(double r, string& i):res(r),info(i){}
- Elem(double r, char* i):res(r),info(i){}
- double res; // 运算出的数据
- string info; // 运算的过程
- bool operator<(const Elem& e) const
- {
- return res < e.res; // 在set的红黑树插入操作中需要用到比较操作
- }
- };
- int A[N]; // 记录N个数据
- // 用二进制数来表示集合和子集的概念,0110表示集合包含第2,3个数
- set<Elem> vset[1<<N]; // 包含4个元素的集合共有16个子集0-15
- set<Elem>& Fork(int m)
- {
- // memo递归
- if (vset[m].size())
- {
- return vset[m];
- }
- for (int i=1; i<=m/2; i++)
- if ((i&m) == i)
- {
- set<Elem>& s1 = Fork(i);
- set<Elem>& s2 = Fork(m-i);
- set<Elem>::iterator cit1;
- set<Elem>::iterator cit2;
- // 得到两个子集合的笛卡尔积,并对结果集合的元素对进行6种运算
- for (cit1=s1.begin(); cit1!=s1.end(); cit1++)
- for (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)
- {
- str = "("+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];
- }
- int main()
- {
- int i;
- for (i=0; i<N; i++)
- cin >> A[i];
- // 递归的结束条件
- 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);//开始1111 表示四个数
- // 显示算出24点的运算过程
- set<Elem>::iterator it;
- for (it=vset[(1<<N)-1].begin();
- it!=vset[(1<<N)-1].end(); it++)
- {
- if (abs(it->res-RES) < EPS)
- cout << it->info << endl;
- }
- }
1. <<编程之美>>
2. http://blog.csdn.net/tianshuai11/article/details/7713640
- 编程之美之24点游戏
- 编程之美-24点游戏源码
- 【编程之美】24点游戏
- 编程之美24点游戏感悟
- 编程之美-----24点游戏
- 编程之美—24点游戏
- 编程之美 1.16 24点游戏
- 【编程之美】24点游戏
- 编程之美--1.16 24点游戏
- 编程之美 1.16 24点游戏
- 编程之美 1.16 24点游戏
- 《编程之美》笔记之——24点游戏
- 读书笔记之编程之美 - 1.16 24点游戏
- 编程之美: 24点游戏的解法
- 编程之美读书笔记22 1.16 24点游戏
- 编程之美上24点游戏的实现
- 编程之美1.16——24点游戏
- 编程之美:24点游戏(1.16 P100页)
- 正确理解Navgation的BackItem
- java ResultSet Reflect To Bean
- sae是个不错的平台
- 为什么要把手机的名字取得很复杂?
- JavaScript: 让拖动支持iphone/ipad触摸
- 编程之美-----24点游戏
- delphi 读取IE加载项的注册表项
- XML---添加 删除、编辑、修改并保存、添加、查找、生成XML按钮并完成对应的功能
- 将数据库中的数据导出为XML数据
- JAVA中的空指针异常(java.lang.NullPointerException)
- s3c2440 nandflash启动过程分析
- UML总结之——用例图
- ShellCode 指南
- 既然没死,那就抓紧活着吧