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的顺序了

二、代码实现

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. int mark_int[] = { ,,, };
  5. string mark_char = "+-*/";
  6. double cal(double a, int m, double b)
  7. {
  8. switch (m)
  9. {
  10. case : return a + b;
  11. case : return a - b;
  12. case : return a * b;
  13. case : return a / b;
  14. }
  15. }
  16.  
  17. bool cal1(double a, double b, double c, double d, int m1, int m2, int m3)
  18. {
  19. double r1;
  20. double r2;
  21. double r3;
  22. r1 = cal(a, m1, b);
  23. r2 = cal(r1, m2, c);
  24. r3 = cal(r2, m3, d);
  25. if (r3 == )
  26. {
  27. cout << "(((" << a << mark_char[m1 - ] << b << ")" << mark_char[m2 - ] << c << ")" << mark_char[m3 - ] << d << ")" << endl;
  28. return ;
  29. }
  30. return ;
  31. }
  32.  
  33. bool cal2(int a, int b, int c, int d, int m1, int m2, int m3)
  34. {
  35. double r1;
  36. double r2;
  37. double r3;
  38. r1 = cal(b, m1, c);
  39. r2 = cal(a, m2, r1);
  40. r3 = cal(r2, m3, d);
  41. if (r3 == )
  42. {
  43. cout << "((" << a << mark_char[m1 - ] << "(" << b << mark_char[m2 - ] << c << "))" << mark_char[m3 - ] << d << ")" << endl;
  44. return ;
  45. }
  46. return ;
  47. }
  48.  
  49. bool cal3(int a, int b, int c, int d, int m1, int m2, int m3)
  50. {
  51. double r1;
  52. double r2;
  53. double r3;
  54. r1 = cal(b, m1, c);
  55. r2 = cal(r1, m2, d);
  56. r3 = cal(a, m3, r2);
  57. if (r3 == )
  58. {
  59. cout << "(" << a << mark_char[m1 - ] << "((" << b << mark_char[m2 - ] << c << ")" << mark_char[m3 - ] << d << "))" << endl;
  60. return ;
  61. }
  62. return ;
  63. }
  64.  
  65. bool cal4(int a, int b, int c, int d, int m1, int m2, int m3)
  66. {
  67. double r1;
  68. double r2;
  69. double r3;
  70. r1 = cal(c, m1, d);
  71. r2 = cal(b, m2, r1);
  72. r3 = cal(a, m3, r2);
  73. if (r3 == )
  74. {
  75. cout << "(" << a << mark_char[m1 - ] << "(" << b << mark_char[m2 - ] << "(" << c << mark_char[m3 - ] << d << ")))" << endl;
  76. return ;
  77. }
  78. return ;
  79. }
  80.  
  81. bool cal5(int a, int b, int c, int d, int m1, int m2, int m3)
  82. {
  83. double r1;
  84. double r2;
  85. double r3;
  86. r1 = cal(a, m1, b);
  87. r2 = cal(c, m3, d);
  88. r3 = cal(r1, m2, r2);
  89. if (r3 == )
  90. {
  91. cout << "((" << a << mark_char[m1 - ] << b << ")" << mark_char[m2 - ] << "(" << c << mark_char[m3 - ] << d << "))" << endl;
  92. return ;
  93. }
  94. return ;
  95. }
  96.  
  97. bool all_cal(int a, int b, int c, int d)
  98. {
  99. for (int i = ; i <= ; i++)
  100. for (int j = ; j <= ; j++)
  101. for (int k = ; k <= ; k++)
  102. {
  103. 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)
  104. return ;
  105. }
  106. return ;
  107. }
  108.  
  109. bool judge(int a, int b, int c, int d)
  110. {
  111. int all[][] = {
  112. {a,b,c,d},{a,b,d,c},{a,c,b,d},{a,c,d,b},{a,d,b,c},{a,d,c,b},
  113. {b,a,c,d},{b,a,d,c},{b,c,a,d},{b,c,d,a},{b,d,a,c},{b,d,c,a},
  114. {c,a,b,d},{c,a,d,b},{c,b,a,d},{c,b,d,a},{c,d,a,b},{c,d,b,a},
  115. {d,a,b,d},{d,a,d,b},{d,b,a,c},{d,b,c,a},{d,c,a,b},{d,c,b,a},
  116. };
  117. for (int i = ; i < ; i++)
  118. {
  119. if (all_cal(all[i][], all[i][], all[i][], all[i][]))
  120. return ;
  121. }
  122. return ;
  123. }
  124.  
  125. int main()
  126. {
  127. int a, b, c, d;
  128. cin >> a >> b >> c >> d;
  129. if (!judge(a, b, c, d))
  130. cout << "凑不成24点" << endl;
  131.  
  132. }

三、代码解释

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

  1. int mark_int[] = { ,,, };
  2. string mark_char = "+-*/";
  3. double cal(double a, int m, double b)
  4. {
  5. switch (m)//用switch来进行运算符的选择
  6. {
  7. case : return a + b;
  8. case : return a - b;
  9. case : return a * b;
  10. case : return a / b;
  11. }
  12. }

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

  1. bool cal1(double a, double b, double c, double d, int m1, int m2, int m3)
  2. {
  3. double r1;
  4. double r2;
  5. double r3;
  6. r1 = cal(a, m1, b);
  7. r2 = cal(r1, m2, c);
  8. r3 = cal(r2, m3, d);
  9. if (r3 == )
  10. {
  11. cout << "(((" << a << mark_char[m1 - ] << b << ")" << mark_char[m2 - ] << c << ")" << mark_char[m3 - ] << d << ")" << endl;
  12. return ;
  13. }
  14. return ;
  15. }//第一种r1=a$b,r2=r1$c,r3=r2$d;
  16.  
  17. bool cal2(int a, int b, int c, int d, int m1, int m2, int m3)
  18. {
  19. double r1;
  20. double r2;
  21. double r3;
  22. r1 = cal(b, m1, c);
  23. r2 = cal(a, m2, r1);
  24. r3 = cal(r2, m3, d);
  25. if (r3 == )
  26. {
  27. cout << "((" << a << mark_char[m1 - ] << "(" << b << mark_char[m2 - ] << c << "))" << mark_char[m3 - ] << d << ")" << endl;
  28. return ;
  29. }
  30. return ;
  31. }//第二种r1=b$c,r2=a$r1,r3=r2$d;
  32.  
  33. bool cal3(int a, int b, int c, int d, int m1, int m2, int m3)
  34. {
  35. double r1;
  36. double r2;
  37. double r3;
  38. r1 = cal(b, m1, c);
  39. r2 = cal(r1, m2, d);
  40. r3 = cal(a, m3, r2);
  41. if (r3 == )
  42. {
  43. cout << "(" << a << mark_char[m1 - ] << "((" << b << mark_char[m2 - ] << c << ")" << mark_char[m3 - ] << d << "))" << endl;
  44. return ;
  45. }
  46. return ;
  47. }//第三种r1=b$c,r2=r1$d,r3=a$r2;
  48.  
  49. bool cal4(int a, int b, int c, int d, int m1, int m2, int m3)
  50. {
  51. double r1;
  52. double r2;
  53. double r3;
  54. r1 = cal(c, m1, d);
  55. r2 = cal(b, m2, r1);
  56. r3 = cal(a, m3, r2);
  57. if (r3 == )
  58. {
  59. cout << "(" << a << mark_char[m1 - ] << "(" << b << mark_char[m2 - ] << "(" << c << mark_char[m3 - ] << d << ")))" << endl;
  60. return ;
  61. }
  62. return ;
  63. }//第四种r1=c$d,r2=b$r1,r3=a$r2;
  64.  
  65. bool cal5(int a, int b, int c, int d, int m1, int m2, int m3)
  66. {
  67. double r1;
  68. double r2;
  69. double r3;
  70. r1 = cal(a, m1, b);
  71. r2 = cal(c, m3, d);
  72. r3 = cal(r1, m2, r2);
  73. if (r3 == )
  74. {
  75. cout << "((" << a << mark_char[m1 - ] << b << ")" << mark_char[m2 - ] << "(" << c << mark_char[m3 - ] << d << "))" << endl;
  76. return ;
  77. }
  78. return ;
  79. }//第五种r1=a$b,r2=c$d,r3=r1$r2;

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

  1. bool all_cal(int a, int b, int c, int d)
  2. {
  3. for (int i = ; i <= ; i++)
  4. for (int j = ; j <= ; j++)
  5. for (int k = ; k <= ; k++)
  6. {
  7. 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)
  8. return ;
  9. }
  10. return ;
  11. }

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

  1. bool judge(int a, int b, int c, int d)
  2. {
  3. int all[][] = {
  4. {a,b,c,d},{a,b,d,c},{a,c,b,d},{a,c,d,b},{a,d,b,c},{a,d,c,b},
  5. {b,a,c,d},{b,a,d,c},{b,c,a,d},{b,c,d,a},{b,d,a,c},{b,d,c,a},
  6. {c,a,b,d},{c,a,d,b},{c,b,a,d},{c,b,d,a},{c,d,a,b},{c,d,b,a},
  7. {d,a,b,d},{d,a,d,b},{d,b,a,c},{d,b,c,a},{d,c,a,b},{d,c,b,a},
  8. };
  9. for (int i = ; i < ; i++)
  10. {
  11. if (all_cal(all[i][], all[i][], all[i][], all[i][]))
  12. return ;
  13. }
  14. return ;
  15. }

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

  1. int main()
  2. {
  3. int a, b, c, d;
  4. cin >> a >> b >> c >> d;
  5. if (!judge(a, b, c, d))
  6. cout << "凑不成24点" << endl;
  7.  
  8. }

失败的话会显示“凑不成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. PHP zip_read() 函数

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

  2. PHP xml_parser_create_ns() 函数

    定义和用法 xml_parser_create_ns() 函数创建带有命名空间支持的 XML 解析器.高佣联盟 www.cgewang.com 如果成功,该函数则返回可被其它 XML 函数使用的资源句 ...

  3. 读书笔记《数据结构与算法JavaScript描述》第一章

    第一章JavaScript的编程环境和模型 1.2JavaScript编程实践 1.2.1 声明和初始化变量 JavaScript中的变量默认为全局变量,如果初始化未被声明的变量,该变量就成了一个全局 ...

  4. Python分析6000家破产IT公司

    前一阵有个字节跳动的程序员火了,年仅28岁实现了财务自由,宣布提前退休.最直接的原因是选择了一家发展前景很好的创业公司.当然平时我们经常能听到,某某人加入创业公司,xx年后公司上市,身价暴涨,财务自由 ...

  5. 树状图展示终端目录内容-tree

    以树状图列出目录的内容,让你一目了然 执行 tree 指令,它会列出指定目录下的所有文件,包括子目录里的文件. 安装 我们通过包管理工具可以方便的安装它 mac - brew install tree ...

  6. syslog协议及rsyslog服务全解析

    背景:需求来自于一个客户想将服务器的日志转发到自己的日志服务器上,所以希望我们能提供这个转发的功能,同时还要满足syslog协议. 一.什么是syslog协议 1.介绍(略) 2.syslog标准协议 ...

  7. 9、Java 常用类 Math,Number子类,String,Character

    本小节主要介绍一些如何去使用Java提供的类如何去使用?如何在实战中使用?从来没有用过的如何去学习? 分享一下发哥的学习方法? 1.针对性的学习 在理解自己的需求或者要做某一块的内容后,有针对性,选择 ...

  8. 将vscode打造成强大的C/C++ IDE

    一.安装 你可以直接从微软官网下载,如果你想要一个纯净的vscode(微软官方的有一项商标.一个插件库.一个 C# 调试器以及遥测),可以手动编译https://github.com/microsof ...

  9. JS学习第二天

    数组: var arr1=[2,5,6];    定义时直接给数组元素赋值 var arr2=[];   定义一个空数组 var arr3=new Array();     定义一个空数组并通过索引来 ...

  10. 2020-04-22:谈谈JDK1.8下的HashMap在并发情况下链表成环的过程。(挖)

    福哥答案2020-04-22: jdk1.8下的hashmap采用的是尾插法,不会有链表成环的问题.jdk1.7下采用的头插***有链表成环的问题. hashmap成环原因的代码出现在transfer ...