经典游戏--24点--c++代码实现和总体思路(简单暴力向)
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++代码实现和总体思路(简单暴力向)的更多相关文章
- 经典趣味24点游戏程序设计(python)
一.游戏玩法介绍: 24点游戏是儿时玩的主要益智类游戏之一,玩法为:从一副扑克中抽取4张牌,对4张牌使用加减乘除中的任何方法,使计算结果为24.例如,2,3,4,6,通过( ( ( 4 + 6 ) - ...
- C++复现经典游戏——扫雷
国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码.这两天想要实现的内容是Windows上的一个经典游戏——扫雷.相信90后和一些上班族对此并不陌生.然而,从win8开始,扫雷就不再是Wind ...
- JAVA开发--游戏24点
也比较简单,写的不好,代码里用到了LOOKANDFELL,QUAQUA8.0的包 package com.Game24; import java.awt.Container; import java. ...
- Cocos2D-ObjC:在RPG游戏中混合Swift代码
我之前写过一个RPG游戏<<熊猫之魂 SoulOfPanda>> 编译器使用的是SpriteBuilder,很好很强大!全部代码都由Objc完成,现在想尝试一下在其中混入Swi ...
- 微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)
微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞 ...
- 微信小游戏 demo 飞机大战 代码分析 (三)(spirit.js, animation.js)
微信小游戏 demo 飞机大战 代码分析(三)(spirit.js, animation.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码 ...
- 微信小游戏 demo 飞机大战 代码分析 (二)(databus.js)
微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...
- 微信小游戏 demo 飞机大战 代码分析 (一)(game.js, main.js)
微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...
- Unity2017 经典游戏开发教程 算法分析与实现 (张帆 著)
https://meta.box.lenovo.com/link/view/82c451b41ce34e81a4b34cb46747d3d5 第1章 熟悉Unity软件的操作 第2章 打地鼠 (已看) ...
随机推荐
- PHP zip_read() 函数
定义和用法 zip_read() 函数读取打开的 zip 档案中的下一个文件.高佣联盟 www.cgewang.com 如果成功,该函数则返回包含 zip 档案中一个文件的资源.如果没有更多的项目可供 ...
- PHP xml_parser_create_ns() 函数
定义和用法 xml_parser_create_ns() 函数创建带有命名空间支持的 XML 解析器.高佣联盟 www.cgewang.com 如果成功,该函数则返回可被其它 XML 函数使用的资源句 ...
- 读书笔记《数据结构与算法JavaScript描述》第一章
第一章JavaScript的编程环境和模型 1.2JavaScript编程实践 1.2.1 声明和初始化变量 JavaScript中的变量默认为全局变量,如果初始化未被声明的变量,该变量就成了一个全局 ...
- Python分析6000家破产IT公司
前一阵有个字节跳动的程序员火了,年仅28岁实现了财务自由,宣布提前退休.最直接的原因是选择了一家发展前景很好的创业公司.当然平时我们经常能听到,某某人加入创业公司,xx年后公司上市,身价暴涨,财务自由 ...
- 树状图展示终端目录内容-tree
以树状图列出目录的内容,让你一目了然 执行 tree 指令,它会列出指定目录下的所有文件,包括子目录里的文件. 安装 我们通过包管理工具可以方便的安装它 mac - brew install tree ...
- syslog协议及rsyslog服务全解析
背景:需求来自于一个客户想将服务器的日志转发到自己的日志服务器上,所以希望我们能提供这个转发的功能,同时还要满足syslog协议. 一.什么是syslog协议 1.介绍(略) 2.syslog标准协议 ...
- 9、Java 常用类 Math,Number子类,String,Character
本小节主要介绍一些如何去使用Java提供的类如何去使用?如何在实战中使用?从来没有用过的如何去学习? 分享一下发哥的学习方法? 1.针对性的学习 在理解自己的需求或者要做某一块的内容后,有针对性,选择 ...
- 将vscode打造成强大的C/C++ IDE
一.安装 你可以直接从微软官网下载,如果你想要一个纯净的vscode(微软官方的有一项商标.一个插件库.一个 C# 调试器以及遥测),可以手动编译https://github.com/microsof ...
- JS学习第二天
数组: var arr1=[2,5,6]; 定义时直接给数组元素赋值 var arr2=[]; 定义一个空数组 var arr3=new Array(); 定义一个空数组并通过索引来 ...
- 2020-04-22:谈谈JDK1.8下的HashMap在并发情况下链表成环的过程。(挖)
福哥答案2020-04-22: jdk1.8下的hashmap采用的是尾插法,不会有链表成环的问题.jdk1.7下采用的头插***有链表成环的问题. hashmap成环原因的代码出现在transfer ...