C++/Qt 计算24点

文章目录

  • C++/Qt 计算24点
    • 1、用递归分治算法思路及设计
    • 2、暴力穷举法
    • 3、Qt 图片

​ 游戏的算法可描述如下:4个1-10的数字,用加、减、乘、除和括号把数子算成24,每个数字都必须使用到,且只能用一次。
​ 用C++写会更加的方便:

​ 在这本书中要求了表达式中数字的顺序不能改变,所以在7.7节 中提供的算法不具有普遍适应性,但是算法的思路还是很简单并且清晰。不需要多动脑袋。在他的基础上,可以轻易的扩展成一般的算法。

一些比较难的24点计算

  • 1 3 9 10

  • 1 4 5 6

  • 1 5 5 5

  • 2 7 10 10

  • 3 3 7 7

  • 3 3 8 8

1、用递归分治算法思路及设计


【1】最开始是4个数,A、B、C、D。
【2】从4个数中选择两个数,例如 A 和 B 。
【3】将两个数进行运算,R1 = A OP B
【4】运算结果 R1 和 剩余的数字进行运算,R1、C、D
【5】从三个数中选择任意两个数进行运算
【6】继续运算,只至一个数字
【7】用递归方法,计算结果是否为24 ,很容易,但是要输出一条完整的表达式,很复杂,因为其简单的计算思路,值得笔记下来。表达式应该还有需要深思的地方…

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include <string>
#include <map>
using namespace std;
string ops[] = { "#","+","-","*","/","-","/" };
map <string, vector<string> > maps;
static int counts = 3;
string num_string( double n )
{char buf[10];sprintf( buf, "%g", n );return string( buf );
}
double cal( double x, double y, int op )
{switch( op ){case 1:return x + y;case 2:return x - y;case 3:return x * y;case 4:{if( y == 0 )return -1000;return x / y;}default:return -1000;}
}
void findKeys( map <string, vector<string> > &m, string &v )
{map <string, vector<string> >::iterator it;it = m.find( v );if( it != m.end() && counts > 0 ){counts--;cout << "(";for( int i = 0; i < 3; i++ ){findKeys( m, it->second[i] );}cout << ")";}else{cout << v;}
}
bool is24( vector<double> a )
{bool find = false;if( a.size() == 1 )return fabs( a[0] - 24 ) < 10E-5;for( int i = 0; i < a.size(); i++ ){vector<double> b( a );b.erase( b.begin() + i );for( int j = 0; j < b.size(); j++ ){vector<double> c( b );c.erase( c.begin() + j );for( int op = 1; op <= 4; op++ ){vector<double> d( c );double r = cal( a[i], b[j], op );if( r < 0 )continue;elsed.push_back( r );if( is24( d ) ){find = true;vector<string> res;res.push_back( num_string( a[i] ) );res.push_back( ops[op] );res.push_back( num_string( b[j] ) );maps[num_string( r )] = res;return true;}}}}return false;
}
int main()
{vector<double> a( 4, 0 );while( cin >> a[0] >> a[1] >> a[2] >> a[3] ){maps.clear();counts = 3;if( is24( a ) ){cout << "true" << endl;string s( "24" );findKeys( maps, s);cout << " = 24" << endl;}else cout << "false" << endl;}
}

2、暴力穷举法


【1】四个数, 穷举 A、B、C、D
【2】三个符号,穷举 +、-、×、÷
【3】两种模式
【3.1】组成表达式,((A OP1 B) OP2 C ) OP3 D
【3.2】组成表达式,(A OP1 B) OP3 (C OP2 D)
【4】注意:减法和除法两个数字交换顺序后,会有不同结果,所以四则运算要分成6种。
对于减法,要检查是否为负数;对于除法,还要检查除数是否为0。

此时每一个数字和符号都已确定,可直接组合成完整的表达式。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include <string>
#include <map>
using namespace std;
string ops[] = { "#","+","-","*","/","-","/" };
string num_string( double n )
{char buf[10];sprintf( buf, "%g", n );return string( buf );
}
double cal( double x, double y, int op )
{switch( op ){case 1:return x + y;case 2:return x - y;case 3:return x * y;case 4:{if( y == 0 )return -1000;return x / y;}case 5:return y - x;case 6:{if( x == 0 )return -1000;return y / x;}default:return -1000;}
}
bool findString( vector<string> &vec, const string &str )
{for( const string var : vec ){if( var == str )return true;}return false;
}
bool is24( vector<double> a )
{vector < string > results;bool find = false;string res;  //可以考虑使用逆波兰表达式,脱去括号,求得最终的表达式,加入表达式集,去除相同的部分for( int A = 0; A < 4; A++ ){for( int B = 0; B < 4; B++ ){if( B == A ) continue;for( int C = 0; C < 4; C++ ){if( C == A || C == B ) continue;for( int D = 0; D < 4; D++ ){if( D == A || D == B || D == C ) continue;for( int op1 = 1; op1 <= 4; op1++ )for( int op2 = 1; op2 <= 6; op2++ )for( int op3 = 1; op3 <= 6; op3++ ){double r1 = cal( a[A], a[B], op1 );    //  (A op1 B)    ||  (B op1 A)if( r1 < 0 )continue;double r21 = cal( r1, a[C], op2 );       //  (r1 op2 C)   ||  (C op2 r1)double r31 = cal( r21, a[D], op3 );      //  (r21 op2 D) ||  (D op2 r21)if( fabs( r31 - 24 ) < 10E-5 && ( r21 >= 0 ) ){//cout << "r31\n";find = true;if( op1 < 5 )res = "(" + num_string( a[A] ) + ops[op1] + num_string( a[B] ) + ")";elseres = "(" + num_string( a[B] ) + ops[op1] + num_string( a[A] ) + ")";if( op2 < 5 )res = "(" + res + ops[op2] + num_string( a[C] ) + ")";elseres = "(" + num_string( a[C] ) + ops[op2] + res + ")";if( op3 < 5 )res = res + ops[op3] + num_string( a[D] );elseres = num_string ( a[D] ) + ops[op3] + res;//检查是否有同样的表达式if( !findString( results, res ) )results.push_back( res );elsecontinue;cout << res << "= 24" << endl;}double r22 = cal( a[C], a[D], op2 );   //  (C op2 D)  ||  (D op2 C)double r32 = cal( r1, r22, op3 );      //  (r1 op2 r22)   ||  (r22 op2 r1)if( fabs( r32 - 24 ) < 10E-5 && ( r22 >= 0 ) ){find = true;string temp;if( op1 < 5 )res = "(" + num_string( a[A] ) + ops[op1] + num_string( a[B] ) + ")";elseres = "(" + num_string( a[B] ) + ops[op1] + num_string( a[A] ) + ")";if( op2 < 5 )temp = "(" + num_string( a[C] ) + ops[op2] + num_string( a[D] ) + ")";elsetemp = "(" + num_string( a[D] ) + ops[op2] + num_string( a[C] ) + ")";if( op3 < 5 )res = res + ops[op3] + temp;elseres = temp + ops[op3] + res;//检查是否有同样的表达式if( !findString( results, res ) )results.push_back( res );elsecontinue;cout << res << "= 24" << endl;}}}}}}if( !find ){cout << "Sorry ,无法计算\n";return false;}elsereturn true;
}
int main()
{vector<double> a( 4, 0 );while( cin >> a[0] >> a[1] >> a[2] >> a[3] ){is24( a );}
}

3、Qt 图片

#include "Widget.h"
#include <QtWidgets>
QString ops[] = { "#","+","-","*","/","-","/" };
int num[] = { 0,1,7,5,10 };
int idx = 0;
Widget::Widget(QWidget *parent) : QWidget(parent)
{QPalette palette;palette.setColor(QPalette::Window,Qt::red);QHBoxLayout *labsLayout = new QHBoxLayout;for (int i = 0; i < 4; ++i) {labs[i] = new QLabel;labs[i]->setAutoFillBackground(true);labs[i]->setPalette(palette);labs[i]->setFrameStyle(QFrame::Panel );labs[i]->setAlignment(Qt::AlignCenter);labs[i]->setMinimumHeight(50);labs[i]->setMargin(10);labsLayout->addWidget(labs[i]);}QGridLayout *btnsLayout = new QGridLayout;for (int i = 0; i < 10; ++i) {QPushButton *btn = new QPushButton(QString::number(i+1));connect(btn,&QPushButton::clicked,[=](){labs[idx]->setText(btn->text());idx +=1;if(idx==1){for (int i = 1; i < 4; ++i) {labs[i]->setText("");}edit->clear();}if(idx==4){idx %= 4;get24();}});btnsLayout->addWidget(btn,i/5,i%5);}edit = new QTextEdit;edit->setReadOnly(true);QVBoxLayout *mainLayout = new QVBoxLayout(this);mainLayout->addLayout(labsLayout);mainLayout->addWidget(edit);mainLayout->addLayout(btnsLayout);
}double Widget::cal(double x, double y, int op)
{switch( op ){case 1:return x + y;case 2:return x - y;case 3:return x * y;case 4:{if( y == 0 )return -1000;return x / y;}case 5:return y - x;case 6:{if( x == 0 )return -1000;return y / x;}default:return -1000;}
}bool Widget::findString(QVector<QString> &vec, const QString &str)
{for( const QString var : vec ){if( var == str )return true;}return false;
}void Widget::get24()
{num[1] = labs[0]->text().toInt();num[2] = labs[1]->text().toInt();num[3] = labs[2]->text().toInt();num[4] = labs[3]->text().toInt();QVector < QString > results;bool find = false;QString res;  //可以考虑使用逆波兰表达式,脱去括号,求得最终的表达式,加入表达式集,去除相同的部分for( int A = 1; A <= 4; A++ ){for( int B = 1; B <= 4; B++ ){if( B == A ) continue;for( int C = 1; C <= 4; C++ ){if( C == A || C == B ) continue;for( int D = 1; D <= 4; D++ ){if( D == A || D == B || D == C ) continue;for( int op1 = 1; op1 <= 4; op1++ )for( int op2 = 1; op2 <= 6; op2++ )for( int op3 = 1; op3 <= 6; op3++ ){double r1 = cal( num[A], num[B], op1 );    //  (A op1 B) ||  (B op1 A)if( r1 < 0 )continue;double r21 = cal( r1, num[C], op2 );       //  (r1 op2 C) ||  (C op2 r1)double r31 = cal( r21, num[D], op3 );      //  (r21 op2 D)   ||  (D op2 r21)//                                if( r31 == 24 && ( r21 >= 0 ) )if( qAbs(r31 - 24)<10E-5 && ( r21 >= 0 ) ){//cout << "r31\n";find = true;if( op1 < 5 )res = "(" + QString::number( num[A] ) + ops[op1] + QString::number( num[B] ) + ")";elseres = "(" + QString::number( num[B] ) + ops[op1] + QString::number( num[A] ) + ")";if( op2 < 5 )res = "(" + res + ops[op2] + QString::number( num[C] ) + ")";elseres = "(" + QString::number( num[C] ) + ops[op2] + res + ")";if( op3 < 5 )res = res + ops[op3] + QString::number( num[D] );elseres = QString::number( num[D] ) + ops[op3] + res;//检查是否有同样的表达式if( !findString( results, res ) )results.push_back( res );elsecontinue;//                                    qDebug() << res << "= 24" ;edit->append(res+" = 24");}double r22 = cal( num[C], num[D], op2 );   //  (C op2 D)  ||  (D op2 C)double r32 = cal( r1, r22, op3 );          //  (r1 op2 r22)   ||  (r22 op2 r1)if( qAbs(r32 - 24)<10E-5 && ( r22 >= 0 ) ){find = true;QString temp;if( op1 < 5 )res = "(" + QString::number( num[A] ) + ops[op1] + QString::number( num[B] ) + ")";elseres = "(" + QString::number( num[B] ) + ops[op1] + QString::number( num[A] ) + ")";if( op2 < 5 )temp = "(" + QString::number( num[C] ) + ops[op2] + QString::number( num[D] ) + ")";elsetemp = "(" + QString::number( num[D] ) + ops[op2] + QString::number( num[C] ) + ")";if( op3 < 5 )res = res + ops[op3] + temp;elseres = temp + ops[op3] + res;//检查是否有同样的表达式if( !findString( results, res ) )results.push_back( res );elsecontinue;//                                    qDebug() << res << "= 24";edit->append(res+" = 24");}}}}}}if( !find )edit->append("Sorry ,无法计算") ;elseedit->moveCursor(QTextCursor::Start);
}

有感兴趣的 可以直接下载 0 积分
https://download.csdn.net/download/hitzsf/85750810, 0积分下载

C++/Qt 计算24点相关推荐

  1. 24点游戏java_使用java编写计算24点游戏程序

    初学java,编写了一个计算24点的程序,时间有限,有些粗糙,不过可以使用. //-------------Cal24.java--------------- //计算24点程序 //作者:徒步天下( ...

  2. c#和javascript分别轻松实现计算24点

    24点游戏介绍:给出4个1-9之间的整数(ms我当年玩的时候是用扑克牌),其中每个数字必须且只用一次:任意使用+-*/ ( ),构造出一个表达式,使得最终结果为24,这就是常见的算24点的游戏(我的老 ...

  3. 计算机公式求时间差公式,24时间差计算公式 excel中计算24小时

    excel中计算24小时制时间差 怎样在excel中计算24小时制时间差,在一天之内的小编会,不过不在一天之内外套一个MOD函数,就行了,这样试试 =MOD("0:36"-&quo ...

  4. 1224 红魔馆的纸牌游戏 (计算24点,dfs)

    Description 红魔馆的蕾米莉亚大小姐一天发现人类有一种叫做24点的游戏,于是就带着一副不知哪里弄来的扑克牌到图书馆找帕秋莉玩 24点游戏的规则:从一副牌中随机抽取4张牌,牌的点数为1到13之 ...

  5. 阿里云云计算 24 SLB的概念

    阿里云云计算 24 SLB的概念 参考 https://edu.aliyun.com/lesson_547_21891#_21891

  6. 使用Scala语言开发GUI界面的计算24点的游戏应用

    今年开始学习Scala语言,对它的强大和精妙叹为观止,同时也深深感到,要熟练掌握这门语言,还必须克服很多艰难险阻. 这时,我就在想,如果能有一种方式,通过实际的应用实例,以寓教于乐的方式,引导我们逐步 ...

  7. 计算24点游戏精化算法剖析

    很多人都玩过这个数学味儿很浓的益智游戏:抽出4张扑克牌,牌上的点数代表四个数字,花牌视为1点(有的把J.Q.K分别视为11.12.13点),玩家中谁最先运用加减乘除四则运算,由这四个数计算出24,谁就 ...

  8. 计算24点的程序及分析过程

    计算24点的程序及分析过程 最近正在学习数据结构.和同事闲聊时,聊到了24点的问题(就是给出4个数,然后用加减剩除及括号算出24来),记得前一阵还在网上看了一道24点的题: 5 5 5 1 ,如何算出 ...

  9. Python之计算24点

    完整的代码如下: # -*- coding: utf-8 -*- import itertools#with brackets def with_brackets(lst, ops_lst):for ...

  10. 用扑克牌计算24点(c语言)

    用扑克牌计算24点 题目 答案 注意 参考 题目 答案 #include<stdio.h>float operation(float a,float b,char c) {switch(c ...

最新文章

  1. 一元操作符和使用Number()方法的区别
  2. PHP文件操作常用函数总结
  3. 绝不重新定义继承而来的缺省值参数
  4. 120天的烧脑只为孩子设计一套教具~
  5. 【C++深度剖析教程33】C++中的构造函数与析构函数是否可以为虚函数
  6. 2005年最具钱途的人才:软件研发炙手可热
  7. 今日心得:人生就像一杯茶,不会苦一辈子但会苦一阵子
  8. 数论19——高斯消元
  9. 基于PHP的汉服文化交流平台 毕业设计-附源码240903
  10. netron配置和使用
  11. 分布式会议系统中的服务器,多功能会议系统分配服务器质量过硬
  12. centos7安装erlang
  13. 蓝桥杯 带分数 By Assassin
  14. spring cloud alibaba全家桶集合
  15. Arcpy处理月NDVI,最大合成法合成年NDVI
  16. 简单的图标移入效果(css缩放)
  17. 【学习资料】中国开放大学-电大-《教育学》形考作业答案(2018).docx
  18. 参考文献中在作者后面的M J ,B等是什么意思
  19. 光耦,磁耦,容耦的区别
  20. ​势头强劲的 Python PK 强大的 C++,究竟谁更胜一筹?

热门文章

  1. 微信分享网页时自定义标题描述和图片
  2. 图片加载失败,img触发错误显示默认图片
  3. 【Faster R-CNN论文精度系列】原文精析
  4. 医院信息系统源码 HIS源码
  5. @PreAuthorize、@Secured、 @RolesAllowed优先级
  6. Ubuntu安装布谷鸟沙盒
  7. 通过京东白条了解资产证券化
  8. centos 基础镜像中安装失败,提示:Error: Failed to download metadata for repo ‘AppStream‘: Cannot prepare internal
  9. 商务周刊封面:别了,摩托罗拉
  10. 生成对抗网络 Generative Adversarial Nets(GAN)详解