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. dp入门例题(1)

    按摩师问题 https://leetcode-cn.com/problems/the-masseuse-lcci/ (找好状态转移方程) 今天只和昨天的状态相关,依然是分类讨论: 今天不接受预约:或者 ...

  2. linux root 与普通用户之间的切换

    test@ubuntu:~$ su Password:  root@ubuntu:/home/uu# 也可以是从root用户切换到普通用户.如果当前是root用户,那么切换成普通用户uu用以下命令:s ...

  3. SpringBoot之整合Quartz调度框架-基于Spring Boot2.0.2版本

    1.项目基础 项目是基于Spring Boot2.x版本的 2.添加依赖 <!-- quartz依赖 --> <dependency> <groupId>org.s ...

  4. 使用Spring Validation优雅地校验参数

    写得好的没我写得全,写得全的没我写得好 引言 不知道大家平时的业务开发过程中 controller 层的参数校验都是怎么写的?是否也存在下面这样的直接判断? public String add(Use ...

  5. PHP stripcslashes() 函数

    实例 删除 "World!" 前面的反斜杠: <?php高佣联盟 www.cgewang.comecho stripslashes("Hello World!&qu ...

  6. PHP attributes() 函数

    实例 返回 XML 的 body 元素的属性和值: <?php$note=<<<XML<note><to>Tove</to>高佣联盟 www ...

  7. IDEA、maven创建webapp项目

      maven官方入门指南:http://maven.apache.org/guides/getting-started/index.html 推荐跟着官方文档学习噢~   IDEA.maven创建w ...

  8. SpringBoot之Quartz基础

    前言:由于我们本项目选用的Springboot来整合Quartz,官方给我们提供了启动器所以很简单.在以前的版本我们想要使用Quartz需要引入的依赖如下: <dependency> &l ...

  9. 31-关键字:final

    final:最终的 1.可以用来修饰:类.方法.变量 2.具体的: 2.1 final 用来修饰一个类:此类不能被其他类所继承. * 比如:String类.System类.StringBuffer类 ...

  10. CSS基础知识(上)

    1.创建结构化.语义丰富HTML 语义化标记是优秀HTML文档的基础. 语义化标记意味着在正确的地方使用正确的元素,从而得到有意义的文档. 有意义的文档可以确保尽可能多的人都能够使用. 1.1 ID和 ...