24点

  24点是一个非常经典的游戏,从扑克牌里抽4张牌,其中J=11,Q=12,K=13,然后经过+,-,*,/,(),的计算后,使得计算得值为24,例如抽到1,2,2,5四张牌,那么

  (1+5)*(2+2)=24;

  这就是可以凑成24点的一种情况,作为一个经典题目,在leetcode上也有对应的题目进行练习

  PS 看见知乎大佬有一种必24点的算法,但是要用到阶乘和次方 式子为(a0+b0+c0+d0)! =24

一、总体思路

  1.因为是简单暴力向的,所以我们的做法就是直接穷举出所有可能的情况,首先是考虑四个数a,b,c,d的排列情况

    如b,a,c,d等等,通过排列组合可以得到 4*3*2*1 = 24 种情况

  2.然后考虑a,b,c,d中的三个运算符的情况设一个自定义的运算符为$,$可以是+,-,*,/中的任意一个

    则有 a$b$c$d 这个式子,同样,运算符的可能性有 3*4 = 12 种

  3.最后考虑()的情况,我们规定,每次一对()只框住两个数,比如a+b+c+d =(((a+b)+c)+d) = ((r1+c)+d)=(r2+d)=r3(其中r1=a+b,r2=r1+c,r3=r2+d)

    ()的情况其实就是运算优先级的问题,无论运算符是什么,都一定是先运算括号里的内容

    所以我们可以穷举出情况

    第一种r1=a$b,r2=r1$c,r3=r2$d;

    第二种r1=b$c,r2=a$r1,r3=r2$d;

    第三种r1=b$c,r2=r1$d,r3=a$r2;

    第四种r1=c$d,r2=b$r1,r3=a$r2;

    第五种r1=a$b,r2=c$d,r3=r1$r2;

  仔细观察不难发现,我们控制了运算符和数字的绝对顺序从左到右的顺序严格是a$b$c$d,不论任何情况都不会改变abcd的顺序,是因为我们在上面已经排出来了所有的24种情况,所以我们这就可以严格控制abcd的顺序了

二、代码实现

 #include <iostream>
#include <string>
using namespace std;
int mark_int[] = { ,,, };
string mark_char = "+-*/";
double cal(double a, int m, double b)
{
switch (m)
{
case : return a + b;
case : return a - b;
case : return a * b;
case : return a / b;
}
} bool cal1(double a, double b, double c, double d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(a, m1, b);
r2 = cal(r1, m2, c);
r3 = cal(r2, m3, d);
if (r3 == )
{
cout << "(((" << a << mark_char[m1 - ] << b << ")" << mark_char[m2 - ] << c << ")" << mark_char[m3 - ] << d << ")" << endl;
return ;
}
return ;
} bool cal2(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(b, m1, c);
r2 = cal(a, m2, r1);
r3 = cal(r2, m3, d);
if (r3 == )
{
cout << "((" << a << mark_char[m1 - ] << "(" << b << mark_char[m2 - ] << c << "))" << mark_char[m3 - ] << d << ")" << endl;
return ;
}
return ;
} bool cal3(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(b, m1, c);
r2 = cal(r1, m2, d);
r3 = cal(a, m3, r2);
if (r3 == )
{
cout << "(" << a << mark_char[m1 - ] << "((" << b << mark_char[m2 - ] << c << ")" << mark_char[m3 - ] << d << "))" << endl;
return ;
}
return ;
} bool cal4(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(c, m1, d);
r2 = cal(b, m2, r1);
r3 = cal(a, m3, r2);
if (r3 == )
{
cout << "(" << a << mark_char[m1 - ] << "(" << b << mark_char[m2 - ] << "(" << c << mark_char[m3 - ] << d << ")))" << endl;
return ;
}
return ;
} bool cal5(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(a, m1, b);
r2 = cal(c, m3, d);
r3 = cal(r1, m2, r2);
if (r3 == )
{
cout << "((" << a << mark_char[m1 - ] << b << ")" << mark_char[m2 - ] << "(" << c << mark_char[m3 - ] << d << "))" << endl;
return ;
}
return ;
} bool all_cal(int a, int b, int c, int d)
{
for (int i = ; i <= ; i++)
for (int j = ; j <= ; j++)
for (int k = ; k <= ; k++)
{
if (cal1(a, b, c, d, i, j, k) == true || cal2(a, b, c, d, i, j, k) == true || cal3(a, b, c, d, i, j, k) == true || cal4(a, b, c, d, i, j, k) == true || cal5(a, b, c, d, i, j, k) == true)
return ;
}
return ;
} bool judge(int a, int b, int c, int d)
{
int all[][] = {
{a,b,c,d},{a,b,d,c},{a,c,b,d},{a,c,d,b},{a,d,b,c},{a,d,c,b},
{b,a,c,d},{b,a,d,c},{b,c,a,d},{b,c,d,a},{b,d,a,c},{b,d,c,a},
{c,a,b,d},{c,a,d,b},{c,b,a,d},{c,b,d,a},{c,d,a,b},{c,d,b,a},
{d,a,b,d},{d,a,d,b},{d,b,a,c},{d,b,c,a},{d,c,a,b},{d,c,b,a},
};
for (int i = ; i < ; i++)
{
if (all_cal(all[i][], all[i][], all[i][], all[i][]))
return ;
}
return ;
} int main()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
if (!judge(a, b, c, d))
cout << "凑不成24点" << endl; }

三、代码解释

先做一个计算两个数的函数,用数组int mark_int[4] = {1,2,3,4}的四个数表示+ - * /,string mark_char是用来最后显示的

 int mark_int[] = { ,,, };
string mark_char = "+-*/";
double cal(double a, int m, double b)
{
switch (m)//用switch来进行运算符的选择
{
case : return a + b;
case : return a - b;
case : return a * b;
case : return a / b;
}
}

我们在实现五种括号的函数,并且我们规定运算一定是 a m1 b m2 c m3 d(m1,m2,m3是三个运算符的代号),如果成功返回运算的过程和true,否则返回false

 bool cal1(double a, double b, double c, double d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(a, m1, b);
r2 = cal(r1, m2, c);
r3 = cal(r2, m3, d);
if (r3 == )
{
cout << "(((" << a << mark_char[m1 - ] << b << ")" << mark_char[m2 - ] << c << ")" << mark_char[m3 - ] << d << ")" << endl;
return ;
}
return ;
}//第一种r1=a$b,r2=r1$c,r3=r2$d; bool cal2(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(b, m1, c);
r2 = cal(a, m2, r1);
r3 = cal(r2, m3, d);
if (r3 == )
{
cout << "((" << a << mark_char[m1 - ] << "(" << b << mark_char[m2 - ] << c << "))" << mark_char[m3 - ] << d << ")" << endl;
return ;
}
return ;
}//第二种r1=b$c,r2=a$r1,r3=r2$d; bool cal3(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(b, m1, c);
r2 = cal(r1, m2, d);
r3 = cal(a, m3, r2);
if (r3 == )
{
cout << "(" << a << mark_char[m1 - ] << "((" << b << mark_char[m2 - ] << c << ")" << mark_char[m3 - ] << d << "))" << endl;
return ;
}
return ;
}//第三种r1=b$c,r2=r1$d,r3=a$r2; bool cal4(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(c, m1, d);
r2 = cal(b, m2, r1);
r3 = cal(a, m3, r2);
if (r3 == )
{
cout << "(" << a << mark_char[m1 - ] << "(" << b << mark_char[m2 - ] << "(" << c << mark_char[m3 - ] << d << ")))" << endl;
return ;
}
return ;
}//第四种r1=c$d,r2=b$r1,r3=a$r2; bool cal5(int a, int b, int c, int d, int m1, int m2, int m3)
{
double r1;
double r2;
double r3;
r1 = cal(a, m1, b);
r2 = cal(c, m3, d);
r3 = cal(r1, m2, r2);
if (r3 == )
{
cout << "((" << a << mark_char[m1 - ] << b << ")" << mark_char[m2 - ] << "(" << c << mark_char[m3 - ] << d << "))" << endl;
return ;
}
return ;
}//第五种r1=a$b,r2=c$d,r3=r1$r2;

接下来是12种的符号的排列情况,如果有一种括号情况满足,我们就返回true,否则返回false

 bool all_cal(int a, int b, int c, int d)
{
for (int i = ; i <= ; i++)
for (int j = ; j <= ; j++)
for (int k = ; k <= ; k++)
{
if (cal1(a, b, c, d, i, j, k) == true || cal2(a, b, c, d, i, j, k) == true || cal3(a, b, c, d, i, j, k) == true || cal4(a, b, c, d, i, j, k) == true || cal5(a, b, c, d, i, j, k) == true)
return ;
}
return ;
}

最后是在总判断函数中写入24种的abcd排列情况

 bool judge(int a, int b, int c, int d)
{
int all[][] = {
{a,b,c,d},{a,b,d,c},{a,c,b,d},{a,c,d,b},{a,d,b,c},{a,d,c,b},
{b,a,c,d},{b,a,d,c},{b,c,a,d},{b,c,d,a},{b,d,a,c},{b,d,c,a},
{c,a,b,d},{c,a,d,b},{c,b,a,d},{c,b,d,a},{c,d,a,b},{c,d,b,a},
{d,a,b,d},{d,a,d,b},{d,b,a,c},{d,b,c,a},{d,c,a,b},{d,c,b,a},
};
for (int i = ; i < ; i++)
{
if (all_cal(all[i][], all[i][], all[i][], all[i][]))
return ;
}
return ;
}

主函数调用judge就完成整个算法了✿✿ヽ(°▽°)ノ✿

 int main()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
if (!judge(a, b, c, d))
cout << "凑不成24点" << endl; }

失败的话会显示“凑不成24点”

其实这个算法的话我写的可以说基本没有优化,就是枚举所有情况实现的,csdn上有大佬是有更好的思路的,这篇文章也是看了csdn的大佬的代码然后自己修修补补写出来的(我原来看的那篇有bug,大佬自己没发现好像。。。)

就酱

睡觉!

  

经典游戏--24点--c++代码实现和总体思路(简单暴力向)的更多相关文章

  1. 经典趣味24点游戏程序设计(python)

    一.游戏玩法介绍: 24点游戏是儿时玩的主要益智类游戏之一,玩法为:从一副扑克中抽取4张牌,对4张牌使用加减乘除中的任何方法,使计算结果为24.例如,2,3,4,6,通过( ( ( 4 + 6 ) - ...

  2. C++复现经典游戏——扫雷

    国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码.这两天想要实现的内容是Windows上的一个经典游戏——扫雷.相信90后和一些上班族对此并不陌生.然而,从win8开始,扫雷就不再是Wind ...

  3. JAVA开发--游戏24点

    也比较简单,写的不好,代码里用到了LOOKANDFELL,QUAQUA8.0的包 package com.Game24; import java.awt.Container; import java. ...

  4. Cocos2D-ObjC:在RPG游戏中混合Swift代码

    我之前写过一个RPG游戏<<熊猫之魂 SoulOfPanda>> 编译器使用的是SpriteBuilder,很好很强大!全部代码都由Objc完成,现在想尝试一下在其中混入Swi ...

  5. 微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)

    微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞 ...

  6. 微信小游戏 demo 飞机大战 代码分析 (三)(spirit.js, animation.js)

    微信小游戏 demo 飞机大战 代码分析(三)(spirit.js, animation.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码 ...

  7. 微信小游戏 demo 飞机大战 代码分析 (二)(databus.js)

    微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...

  8. 微信小游戏 demo 飞机大战 代码分析 (一)(game.js, main.js)

    微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...

  9. Unity2017 经典游戏开发教程 算法分析与实现 (张帆 著)

    https://meta.box.lenovo.com/link/view/82c451b41ce34e81a4b34cb46747d3d5 第1章 熟悉Unity软件的操作 第2章 打地鼠 (已看) ...

随机推荐

  1. python入门神书!|python编程从入门到实践|内附网盘链接带提取码|

    点击此处进入网盘下载地址 提取码:o39n 全书共有20章,书中的简介如下: 本书旨在让你尽快学会 Python ,以便能够编写能正确运行的程序 —— 游戏.数据可视化和 Web 应用程序,同时掌握让 ...

  2. PHP is_executable() 函数

    定义和用法 is_executable() 函数检查指定的文件是否可执行. 如果文件可执行,该函数返回 TRUE. 语法 is_executable(file) 参数 描述 file 必需.规定要检查 ...

  3. PHP zip_read() 函数

    定义和用法 zip_read() 函数读取打开的 zip 档案中的下一个文件.高佣联盟 www.cgewang.com 如果成功,该函数则返回包含 zip 档案中一个文件的资源.如果没有更多的项目可供 ...

  4. P2569 [SCOI2010]股票交易 dp 单调队列优化

    LINK:股票交易 题目确实不算难 但是坑点挺多 关于初值的处理问题我就wa了两次. 所以来谢罪. 由于在手中的邮票的数量存在限制 且每次买入卖出也有限制. 必然要多开一维来存每天的邮票数量. 那么容 ...

  5. 转)Understanding Java Memory Management

    Understanding Java Memory Management - IBM Java Native Interface (JNI) Objects and Code Java Native ...

  6. linux的文件系统管理(ext4-tune2fs-e2fsck-xfs文件系统)

    文件系统管理 文件系统是Linux系统存放文件的空间.文件系统的类型有很多种,CentOS支持多种文件系统,目前常用的是ext4和xfs文件系统.我们以ext4文件系统为例来说明对文件系统的管理. U ...

  7. 利用Data Vault对数据仓库进行建模(二)

    写在前面 本篇先不讨论Data Vault其本身,因为不见得所有人都接受这个.但是里边有一些很不错的东西跟主流的数据仓库方法是有共同点的,所以这里主要讨论这些共同的方法,在笔者看来,无论是Kimbal ...

  8. 我靠!Semaphore里面居然有这么一个大坑!

    这是why的第 59 篇原创文章 荒腔走板 大家好,我是why哥 ,欢迎来到我连续周更优质原创文章的第 59 篇. 上周写了一篇文章,一不小心戳到了大家的爽点,其中一个转载我文章的大号,阅读量居然突破 ...

  9. 实验05——java算术运算符减法

    package cn.tedu.demo; import java.math.BigDecimal; /** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @ver ...

  10. 开启CAN通信学习(二)——基于Kvaser的CAN通信案例

    1 案例硬件介绍 Kvaser是瑞典的一家专门提供CAN和LIN总线分析仪及数据记录仪的公司,在CAN产品开发领域已经有近30年的经验,本案例选择的CAN通信硬件型号是Kvaser Leaf Ligh ...