经典游戏--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章 打地鼠 (已看) ...
随机推荐
- jmeter之断言复制过来的内容也会失败
今天遇到个很纳闷的事儿,就决定记下来,在做jmeter断言的时候,明明我是从相应文本中拷贝出来的内容,但是依旧会断言失败,差了很多资料无果,最终请教了大佬才发现是特殊字符的问题 jmeter断言中不会 ...
- 使用MacOS自带的SVN客户端
原文链接:https://jingyan.baidu.com/article/5552ef479c1554518ffbc92f.html 摘要:mac环境下有自带的SVN服务端和客户端,SVN是许多公 ...
- fpdf fpdi 操作pdf文件 写入中文汉字
今天给公司做一个线上合同签约功能,用户签约后 生成pdf版的文件 .网上搜了搜大概都是用fpdf进行操作的 , 通过fpdi 可以进行读取pdf模板. 在通过继承fpdf 操作现有的pdf文档 ...
- Skill 脚本演示 ycBusNet.il
https://www.cnblogs.com/yeungchie/ ycBusNet.il 用于原理图中按照一定格式,批量创建 Bus . 回到目录
- MySQL中EXPLAIN命令详细解析
很多情况下我们需要知道某条SQL语句的性能,都会通过EXPLAIN命令来查看查询优化器是如何执行的. 如何使用 使用EXPLAIN很简单,只需要在执行的SQL前面加上EXPLAIN即可 explain ...
- 关于 ORA-01033: ORACLE initialization or shutdown in progress
第一步: 这个错误首先查看服务进程是否正常启动: 第二步: 一般情况下第一步都没问题,问题出在可能误删了日志文件: 当然可能不是你删除的,可能被某些清理软件删除的: 或者是其他情况导致日志出错 ...
- ios企业签名为什么会掉签?
我们都知道ios用户无法直接安装App Store之外的应用,对于那些无法上架苹果应用商店的APP,开发者们一般会选择苹果签名的形式. 目前的苹果签名有ios企业签名.超级签名和TF上架这三种 ...
- Ubuntu16.04忘记用户登录密码以及管理员密码,重置密码的解决方案
1. 问题现象: 密码遗忘 2. 问题原因 问题原因,搞不懂,只是修改了/etc/shadow和/etc/sudoers这俩文件 3. 解决方案 在系统开机前常按shift键进入grub界面,如下: ...
- 014_go语言中的变参函数
代码演示 package main import "fmt" func sum(nums ...int) { fmt.Print(nums, " ") toto ...
- Python 进程与多线程
10 进程和多线程 10.1 多进程 # -*- coding: utf-8 -*- import os pid=os.fork() print ('process (%s)start ...' %o ...