草庐IT

24点游戏题库算法分析

ARV000 2023-03-28 原文
一、4数种类分析

统计分析

从标有1-10的数字的10个小球中取出1个小球记录小球的数字,然后将小球放回,如此反复4次取出4小球的数字组成的序号一共有多少种。注意:1.1.8.9 和1.8.1.9 算是一种。

需要分为一下几种情况:

  • 四个小球数字都相等情况:

一个有10种

  • 三个小球数字相等:

一共有10*9种 = 90

  • 两个小球数字相等,另外两个小球数字不相等

一共有10 * ( 9 * 8 /2 )种 = 360

10表示:10个相等的两个小球

( 9 * 8 /2 )表示:另外两个小球不相等的情况。

  • 两个小球数字相等,另外两个小球也相等。

一共有(10*9)/2 中 = 45

  • 四个小球数字都不想等

编辑 = 10* 9 * 8 * 7 / (4 * 3 *2 *1 ) = 210 

总数为=10 + 90 + 360 + 45 + 210 = 715

代码分析

代码中我们可以直接使用遍历的方式进行穷举,

1 . 对比记录列表中的数据是否存在,如果存在就忽略。

2. 如果不存在就添加到列表中。

遍历所有的数据。

#define MAXNUM 10
QList<struNum> initList()
{
    QList<struNum> list;
    for (int i1 = 1;i1 <= MAXNUM; i1++) {
        for (int i2 = 1;i2 <= MAXNUM; i2++) {
            for (int i3 = 1;i3 <= MAXNUM; i3++) {
                for (int i4 = 1;i4 <= MAXNUM; i4++) {
                    struNum num(i1,i2,i3,i4);
                    if(!isInList(num,list)){
                        list.append(num);
                    }
                }
            }
        }
    }
    return list;
}

  

判断是否存在列表中

typedef  struct SNUM{
    SNUM(int num1,int num2,int num3,int num4){
        this->num1 = num1;
        this->num2 = num2;
        this->num3 = num3;
        this->num4 = num4;
    }
    int num1 =0;
    int num2 =0;
    int num3 =0;
    int num4 =0;
    int c = 0;  // 四个数能够计算24算法。
}struNum;
bool isInList(struNum num, QList<struNum> list)
{
    int numList[4] = {num.num1,num.num2,num.num3,num.num4};
    bool result = false;
    for (int i1 = 0 ; i1 < 4; i1 ++) {
        for (int i2 = 0 ; i2 < 4; i2 ++){
            if(i1 == i2) continue;
            for (int i3 = 0 ; i3 < 4; i3 ++){
                if(i2 == i3 || i1 == i3) continue;
                for (int i4 = 0 ; i4 < 4; i4 ++){
                    if(i1 == i4 || i2 == i4 || i3 == i4) continue;
                      foreach(auto item ,list){
                            if(item.num1 == numList[i1]
                                && item.num2 == numList[i2]
                                && item.num3 == numList[i3]
                                && item.num4 == numList[i4]){
                                result = true;
                            }
                      }
                }
            }
        }
    }
    return result;
}

 

二、四数排列算法分析

4个数按照顺序排列,一共有多少种排列方法。

我们可以使用遍历方法,将所有的数字进行遍历,那么可以得到一下算法。可以看到以下算法的步骤需要经过4*4*4*4 次运算。那么我们通过观察可以优化代码算法。

优化前

4*4*4*4 = 256次运算

   int numList[4] = {num1,num2,num3,num4};

   for (int i1 = 0 ; i1 < 4; i1 ++) {
        for (int i2 = 0 ; i2 < 4; i2 ++){
            for (int i3 = 0 ; i3 < 4; i3 ++){
                for (int i4 = 0 ; i4 < 4; i4 ++){
                  if(i1 != i2 && i1 != i3 && i1 != i4 && i2 != i3 && i2 != i4 && i3 != i4){
                        qInfo()<<numList[i1]<<" "<<numList[i2] <<" "<< numList[i3] <<" "<<" "<< numList[i4];
                        c++;
                   }
                }
            }
        }
    }
点击并拖拽以移动

 

 

优化后

4*3*2 = 24 次运算。

 1 int numList[4] = {num1,num2,num3,num4};
 2     int c =0;
 3     for (int i1 = 0 ; i1 < 4; i1 ++) {
 4         for (int i2 = 0 ; i2 < 4; i2 ++){
 5             if(i1 == i2) continue;
 6             for (int i3 = 0 ; i3 < 4; i3 ++){
 7                 if(i2 == i3 || i1 == i3) continue;
 8                 for (int i4 = 0 ; i4 < 4; i4 ++){
 9                     if(i1 == i4 || i2 == i4 || i3 == i4) continue;
10                      qInfo()<<numList[i1]<<" "<<numList[i2] <<" "<< numList[i3] <<" "<<" "<< numList[i4];
11                         c++;
12                 }
13             }
14         }
15     }

 

三、分数计算类

由于计算过程中可能会遇到分数计算,因此我们不能使用int类型直接表示数据,或者是数据运算结果,我们定义一个分数类,专门用来计算分数的,加、减、乘、除,这样可以尽可能保存数据的正确性。

加法

编辑

减法

编辑

乘法

编辑

除法

编辑

LNum.h

 1 #ifndef LNUM_H
 2 #define LNUM_H
 3 
 4 class LNum
 5 {
 6 
 7 public:
 8     LNum(int Molecule);
 9     LNum(int Molecule,int Denominator);
10     int getMolecule();                   // 获取分子
11     int getDenominator();                // 获取分母
12     void setMolecule(int molecule);      // 设置分子
13     void setDenominator(int denominator);// 设置分母
14     double data();
15     LNum operator + ( LNum p1);
16     LNum operator - ( LNum p1);
17     LNum operator * ( LNum p1);
18     LNum operator / ( LNum p1);
19     bool operator ==( LNum p1) ;
20 private:
21     // 分子
22     int m_iMolecule = 1;
23     // 分母
24     int m_iDenominator = 1;
25     void Equivalency();         // 约分
26 
27 };
28 
29 #endif // LNUM_H

 

 LNum.cpp

  1 #include "lnum.h"
  2 
  3 
  4 LNum::LNum(int num)
  5     :m_iMolecule(num)
  6     ,m_iDenominator(1)
  7 {
  8 
  9 }
 10 
 11 LNum::LNum(int Molecule, int Denominator)
 12     :m_iMolecule(Molecule)
 13     ,m_iDenominator(Denominator)
 14 {
 15 
 16 }
 17 
 18 int LNum::getMolecule()
 19 {
 20     Equivalency();
 21     return m_iMolecule;
 22 }
 23 
 24 int LNum::getDenominator()
 25 {
 26     Equivalency();
 27     return  m_iDenominator;
 28 }
 29 
 30 void LNum::setMolecule(int molecule)
 31 {
 32     m_iMolecule = molecule;
 33 }
 34 
 35 void LNum::setDenominator(int denominator)
 36 {
 37     m_iDenominator = denominator;
 38 }
 39 
 40 double LNum::data()
 41 {
 42     Equivalency();
 43     if(m_iDenominator == 1){
 44         return m_iMolecule;
 45     }
 46     return double(m_iMolecule)/double(m_iDenominator);
 47 }
 48 
 49 void LNum::Equivalency()
 50 {
 51     int num = m_iMolecule> m_iDenominator?m_iDenominator:m_iMolecule;
 52 
 53     for (int i  = 2 ; i < num ;i++) {
 54         if(m_iDenominator%i == 0 && m_iMolecule%i ==0){
 55             m_iDenominator = m_iDenominator/i;
 56             m_iMolecule = m_iMolecule/i;
 57             num = m_iMolecule> m_iDenominator?m_iDenominator:m_iMolecule;
 58         }
 59     }
 60 }
 61 
 62 LNum LNum::operator +(LNum p1)
 63 {
 64     LNum res(getMolecule(),getDenominator());
 65     res.setMolecule(getMolecule()*p1.getDenominator() + getDenominator()*p1.getMolecule());
 66     res.setDenominator(getDenominator()*p1.getDenominator());
 67     return  res;
 68 }
 69 
 70 LNum LNum::operator -(LNum p1)
 71 {
 72     LNum res(getMolecule(),getDenominator());
 73     res.setMolecule(getMolecule()*p1.getDenominator() - getDenominator()*p1.getMolecule());
 74     res.setDenominator(getDenominator()*p1.getDenominator());
 75     return  res;
 76 }
 77 
 78 LNum LNum::operator *(LNum p1)
 79 {
 80     LNum res(getMolecule(),getDenominator());
 81     res.setMolecule(getMolecule()*p1.getMolecule());
 82     res.setDenominator(getDenominator()*p1.getDenominator());
 83     return  res;
 84 }
 85 
 86 LNum LNum::operator /(LNum p1)
 87 {
 88     LNum res(getMolecule(),getDenominator());
 89     res.setMolecule(getMolecule()*p1.getDenominator());
 90     res.setDenominator(getDenominator()*p1.getMolecule());
 91     return  res;
 92 }
 93 
 94 bool LNum::operator ==(LNum p1)
 95 {
 96     if (getMolecule() == p1.getMolecule() && getDenominator() == p1.getDenominator()) {
 97         return true;
 98     }
 99     else{
100         return false;
101     }
102 
103 }

 

四、加减乘除操作符遍历

第一步将操作符数字化,方便遍历。可以得到如下公式。x为操作符标识。

 1 double jisuan(LNum num1,LNum num2,int x){
 2     switch (x) {
 3     case 0:
 4         return num1+num2;
 5     case 1:
 6         return num1-num2 ;
 7     case 2:
 8         return num1*num2;
 9     case 3:
10         return num1/num2 ;
11     }
12     return 0;
13 }

 

五、探测4个数是否能计算24

循环遍历4个数的不同位置,并且循环遍历算法。判断其内容是否为24如果是24那么表示可以计算成功。

 1 int is24OK(LNum num1, LNum num2, LNum num3, LNum num4)
 2 {
 3     int result = 0;
 4      QList<struRecordNum> list;
 5     LNum numList[4] = {num1,num2,num3,num4};
 6         // 交换4个数字的顺序。
 7         for (int i1 = 0 ; i1 < 4; i1 ++) {
 8             for (int i2 = 0 ; i2 < 4; i2 ++){
 9                 if(i1 == i2) continue;
10                 for (int i3 = 0 ; i3 < 4; i3 ++){
11                     if(i2 == i3 || i1 == i3) continue;
12                     for (int i4 = 0 ; i4 < 4; i4 ++){
13                         if(i1 == i4 || i2 == i4 || i3 == i4) continue;
14                         //  qInfo()<<numList[i1]<<" "<<numList[i2] <<" "<< numList[i3] <<" "<<" "<< numList[i4];
15                           int x=suanfatongji(numList[i1],numList[i2],numList[i3],numList[i4],&list);
16                           if(x !=0){
17                               qInfo()<<"x:"<<x;
18                               result += x;
19                           }
20                     }
21                 }
22             }
23         }
24         return result;
25 }
26 
27 int suanfatongji(LNum num1, LNum num2, LNum num3, LNum num4, QList<struRecordNum> *list)
28 {
29         LNum sum = 0;
30 
31         int c= 0;
32         for(int i1 = 0 ; i1 < 4; i1 ++){
33             for(int i2 = 0 ; i2 < 4; i2 ++ ){
34                 for(int i3 = 0 ; i3 < 4; i3 ++){
35                     sum = jisuan(jisuan(jisuan (num1,num2,i1),num3,i2),num4,i3) ;
36                     if(24.0  == sum.data()){
37                         // 是否找到相同的算法,因为有重复数字可能导致算法想法和数字相同的情况。
38                         bool result = false;
39                         for(auto item : *list){
40                             if(item.num1 == static_cast<int>(num1.data())
41                             && item.num2 == static_cast<int>(num2.data())
42                             && item.num3 == static_cast<int>(num3.data())
43                             && item.num4 == static_cast<int>(num4.data())
44                             && item.option1 == i1
45                             && item.option2 == i2
46                             && item.option3 == i3){
47                                 result = true;
48                             }
49                         }
50                         if(!result){
51                             struRecordNum tmpItem;
52                             tmpItem.num1 =  static_cast<int>(num1.data());
53                             tmpItem.num2 =  static_cast<int>(num2.data());
54                             tmpItem.num3 =  static_cast<int>(num3.data());
55                             tmpItem.num4 =  static_cast<int>(num4.data());
56                             tmpItem.option1 =  i1;
57                             tmpItem.option2 =  i2;
58                             tmpItem.option3 =  i3;
59                             list->append(tmpItem);
60                              c++;
61                              qInfo()<< "(( "<< num1.data() <<strOption(i1) << num2.data() <<")"<<strOption(i2)<< num3.data()<<")" <<strOption(i3)<< num4.data();
62                         }
63                     }
64                 }
65             }
66         }
67         return c;
68 }

 

六、源码地址

啊渊 / QT博客案例 · GitCode 24点题库分析。

有关24点游戏题库算法分析的更多相关文章

  1. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  2. Python 刷Leetcode题库,顺带学英语单词(31) - 2

    ValidPalindromeGivenastring,determineifitisapalindrome,consideringonlyalphanumericcharactersandignoringcases. [#125]Example:"Aman,aplan,acanal:Panama"isapalindrome."raceacar"isnotapalindrome.Haveyouconsiderthatthestringmightbeempty?Thisisagoodquestiontoaskduringaninterview.Forthepurposeofthisproblem

  3. ruby - 我需要从 facebook 游戏中抓取数据——使用 ruby - 2

    修改(澄清问题)我已经花了几天时间试图弄清楚如何从Facebook游戏中抓取特定信息;但是,我遇到了一堵又一堵砖墙。据我所知,主要问题如下。我可以使用Chrome的检查元素工具手动查找我需要的html-它似乎位于iframe中。但是,当我尝试抓取该iframe时,它​​是空的(属性除外):如果我使用浏览器的“查看页面源代码”工具,这与我看到的输出相同。我不明白为什么我看不到iframe中的数据。答案不是它是由AJAX之后添加的。(我知道这既是因为“查看页面源代码”可以读取Ajax添加的数据,也是因为我有b/c我一直等到我可以看到数据页面之后才抓取它,但它仍然不存在)。发生这种情况是因为

  4. python - Ruby 或 Python 的 3d 游戏引擎? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion是否有适用于这些的3d游戏引擎?

  5. 100个python算法超详细讲解:画直线 - 2

    1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva

  6. 建模分析 | 平面2R机器人(二连杆)运动学与动力学建模(附Matlab仿真) - 2

    目录0专栏介绍1平面2R机器人概述2运动学建模2.1正运动学模型2.2逆运动学模型2.3机器人运动学仿真3动力学建模3.1计算动能3.2势能计算与动力学方程3.3动力学仿真0专栏介绍?附C++/Python/Matlab全套代码?课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。?详情:图解自动驾驶中的运动规划(MotionPlanning),附几十种规划算法1平面2R机器人概述如图1所示为本文的研究本体——平面2R机器人。对参数进行如下定义:机器人广义坐标

  7. 网站日志分析软件--让网站日志分析工作变得更简单 - 2

    网站的日志分析,是seo优化不可忽视的一门功课,但网站越大,每天产生的日志就越大,大站一天都可以产生几个G的网站日志,如果光靠肉眼去分析,那可能看到猴年马月都看不完,因此借助网站日志分析工具去分析网站日志,那将会使网站日志分析工作变得更简单。下面推荐两款网站日志分析软件。第一款:逆火网站日志分析器逆火网站日志分析器是一款功能全面的网站服务器日志分析软件。通过分析网站的日志文件,不仅能够精准的知道网站的访问量、网站的访问来源,网站的广告点击,访客的地区统计,搜索引擎关键字查询等,还能够一次性分析多个网站的日志文件,让你轻松管理网站。逆火网站日志分析器下载地址:https://pan.baidu.

  8. ABB-IRB-1200运动学分析MATLAB RVC工具分析+Simulink-Adams联合仿真 - 2

    一、机器人介绍        此处是基于MATLABRVC工具箱,对ABB-IRB-1200型号的微型机械臂进行正逆向运动学分析,并利Simulink工具实现对机械臂进行具有动力学参数的末端轨迹规划仿真,最后根据机械模型设计Simulink-Adams联合仿真。 图1.ABBIRB 1200尺寸参数示意图ABBIRB 1200提供的两种型号广泛适用于各作业,且两者间零部件通用,两种型号的工作范围分别为700 mm 和 900 mm,大有效负载分别为 7 kg 和5 kg。 IRB 1200 能够在狭小空间内能发挥其工作范围与性能优势,具有全新的设计、小型化的体积、高效的性能、易于集成、便捷的接

  9. 关于Qt程序打包后运行库依赖的常见问题分析及解决方法 - 2

    目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'

  10. ruby - 在 Ruby 中实现 Luhn 算法 - 2

    我一直在尝试用Ruby实现Luhn算法。我一直在执行以下步骤:该公式根据其包含的校验位验证数字,该校验位通常附加到部分帐号以生成完整帐号。此帐号必须通过以下测试:从最右边的校验位开始向左移动,每第二个数字的值加倍。将乘积的数字(例如,10=1+0=1、14=1+4=5)与原始数字的未加倍数字相加。如果总模10等于0(如果总和以零结尾),则根据Luhn公式该数字有效;否则无效。http://en.wikipedia.org/wiki/Luhn_algorithm这是我想出的:defvalidCreditCard(cardNumber)sum=0nums=cardNumber.to_s.s

随机推荐