穷举法解24点游戏

24点游戏:

输入:n1,n2,n3,n4

输出:若能通过+ - * / 和括号混合运算,得到运算结果为24,则输出一个对应的运算表达式

穷举法:

对4个数字全排列有4!=24种排列。

4个数字共需要3个运算符,同一个运算符可以重复出现,则有4x4x4=64种情况。

对于4个数字而言,共有以下5中加括号的方式:

(A(B(CD))),(A((BC)D)),((AB)(CD)),((A(BC))D),(((AB)C)D)。

所以遍历的表达式最多有24*64*5=7680种。即使采用逆波兰表达式,总数不变。

/*24点游戏算法,穷举法: 
f(Array)
{
   if(Array.Length<2)
   {
     if(得到的最终结果是24) 输出表达式
     else 输出无符合要求的表达式
   }
   foreach(从数组中取任意两个数的组合)
   {
      foreach(运算符(+ - * /))
      {
         1、计算该组合在此运算符下的结果
         2、将该组合中的两个数从原数组中删除,并将步骤1的结果放入数组
         3、对新数组递归调用f。如果找到一个表达式就返回
         4、将步骤1的计算结果移除,并将该组合中的两个数重新放回数组中对应的位置
      } 
   }
}     
*/

#include<iostream>
#include<string>
#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)
    {
        //浮点数的比较使用差值与阈值的比较
        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];

            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<4; ++i)
    {
       char buffer[20];
       cout<<"the "<<i+1<<"th number:";
       cin>>x;
       number[i]=x;
       itoa(x,buffer,10);
       result[i]=buffer;
    }
    if(PointsGame(CardsNumber))
      cout<<"Success."<<endl;
    else cout<<"Fail."<<endl;

    return 0;
}

 

作者:阿凡卢

出处:http://www.cnblogs.com/luxiaoxun/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

http://www.cnblogs.com/luxiaoxun/archive/2012/08/07/2626476.html

时间: 2024-10-27 20:53:33

穷举法解24点游戏的相关文章

算法系列(十六) 使用穷举法解猜结果游戏

一. 引言 穷举是解决问题的一种常用思路,当对一个问题无从下手的时候,可以考虑在问题 域允许的范围内将所有可能的结果穷举出来,然后根据正确结果的判断规则对这些结果逐个验证,从而找 出正确的结果.采用穷举的方法求解问题的答案比较适合计算机做,对这种体力活它们没有怨言,本文就 以常见的两个猜结果的题目为例,介绍一下如何通过计算机程序解决此类问题,顺便介绍一下穷举法常见 的算法结构和实现方式. 二. 猜结果游戏的分析过程 先来看一个问题,有五个运动员 (甲.乙.丙.丁.戊)参加运动会,分别获得了一百米

python 穷举法 算24点(史上最简短代码)

本来想用回溯法实现 算24点.题目都拟好了,就是<python 回溯法 子集树模板 系列 -- 7.24点>.无奈想了一天,没有头绪.只好改用暴力穷举法. 思路说明 根据四个数,三个运算符,构造三种中缀表达式,遍历,计算每一种可能 显然可能的形式不止三种.但是,其它的形式要么得不到24点,要么在加.乘意义下可以转化为这三种形式的表达式! 使用内置的eval函数计算中缀表达式,使得代码变得非常简洁! 完整代码 # 作者:hhh5460 # 时间:2017年6月3日 import itertool

《C语言及程序设计》实践项目——穷举法解题

返回:贺老师课程教学链接 说明:穷举法在有些时候,并不是一种最有效率的解决方案,但却是最直观的.初学者依靠这一组问题的解决,将获得程序设计的最直接体验,以及会想问题的头脑. [项目1-小明借书]小明有五本新书,要借给A,B,C三位小朋友,若每人每次只能借一本,则可以有多少种不同的借法?提示:本问题实际上是一个排列问题,即求从5个中取3个进行排列的方法的总数.首先对五本书从1至5进行编号,然后使用穷举的方法.假设三个人分别借这五本书中的一本,当三个人所借的书的编号都不相同时,就是满足题意的一种借阅

C++实践参考解答 穷举法解决组合问题

[项目:穷举法解决组合问题](自选两题完成,其他的想一想即可.当然,全做完收效更好)先阅读例题,领会穷举法(意为"穷尽式列举",也称枚举)的思想,然后自行选题进行解决,掌握这种程序设计的一般方法. 例题:小明有五本新书,要借给A,B,C三位小朋友,若每人每次只能借一本,则可以有多少种不同的借法? 问题分析与算法设计:本问题实际上是一个排列问题,即求从5个中取3个进行排列的方法的总数.首先对五本书从1至5进行编号,然后使用穷举的方法.假设三个人分别借这五本书中的一本,当三个人所借的书的编

用穷举法找出1到100的质数并显示出来

用穷举法找出1到100的质数并显示出来.分别使用while.do-while.for循环语句实现. 1.用while: include<iostream.h> void main() {int i,j,n,m; i=2; while(i<101) {m=1;n=i/2;j=2; while(j<=n) { if(i%j==0) {m=0; breake; } j++; } if(m) cout<<i<<""; i++; } } 2.用do

穷举法破解密码-MPI+VC6.0进行两台PC的并行计算,穷举法破解6-12位的密码(字母和数字组合)的MPI程序

问题描述 MPI+VC6.0进行两台PC的并行计算,穷举法破解6-12位的密码(字母和数字组合)的MPI程序 10C 需要分配任务,任务不知道怎么分配,我打算写控制台程序,先提示输入密码,用"*"显示,然后破解密码,显示密码是什么.怎么写这个程序啊,谢谢各位大神了.我在网上找了好多资料,可是估计是因为编程能力太差,实在写不出来啊.求大家帮帮忙,比较着急这个,谢谢 解决方案 我搭建好了MPI运行环境,只是遇到编程就傻了,实在编不出来,能给出程序吗?本身编程能力比较差,现在马上要交毕业设计

C++基本算法思想之穷举法_C 语言

穷举算法(Exhaustive Attack method)是最简单的一种算法,其依赖于计算机的强大计算能力来穷尽每一种可能性,从而达到求解问题的目的.穷举算法效率不高,但是适应于一些没有规律可循的场合. 穷举算法基本思想穷举算法的基本思想就是从所有可能的情况中搜索正确的答案,其执行步骤如下: (1)对于一种可能的情况,计算其结果. (2)判断结果是否符合要求,如果不满足则执行第(1)步来搜索下一个可能的情况:如果符合要求,则表示寻找到一个正确答案. 在使用穷举法时,需要明确问题的答案的范围,这

要哭了,用穷举法写最长公共子序列

问题描述 网上都是动态规划..但我要穷举法啊在键盘上输入三个字符串,然后输出最长公共子序列...[输入输出样例]输入:cecqbhvaiaedpibalukcabegviapcihlaaugckadceevfdadaepcialaukd输出:Cevapiluk都想到淘宝上买了...可是没有一个店家理我...救我..... 解决方案 解决方案二:你知道查下线段树算法.网上应该有现成的.解决方案三:穷举法是暴力法吗?这个运行起来够吃力啊.这是我写的暴力法./**Tochangethislicense

C语言及程序设计初步例程-40 穷举法解题

贺老师教学链接  C语言及程序设计初步 本课讲解 穷举法求解:百鸡百钱问题:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一.百钱买百鸡,问鸡翁.鸡母.鸡雏各几何? #include <stdio.h> int main() { int x,y,z; //定义数据类型为整型,买鸡和买烤鸡不是一个概念 for(x=0; x<=20; ++x) for(y=0; y<=33; ++y) //穷举中.... for(z=0; z<=100; ++z) if(5*x+3*y+z/3==100