编程之美电子书下载

24点游戏大家都知道:4张牌,可以进行+ - * / 四种运算,可以使用括号,每个牌用一次,任意组合构造表达式使结果为24。

扩展问题:n个整数,四种运算,可使用括号,每个数字使用一次,使表达式结果为 k

下面的算法1和算法2都是穷举,只是穷举的方式不一样,以下给出的两个算法代码都可以计算扩展问题。可能是集合操作原因,算法1的速度明显比算法2快

书上分析如下                                                                                                                               本文地址

编程之美 1.16 24点游戏

 

 

算法1:

编程之美 1.16 24点游戏

编程之美 1.16 24点游戏

算法1代码如下,我在原来的基础上做了一点改动1、从数组中任选两个数时,保证数对前面没有选择过; 2、通过运算符优先级去除多余的括号;3、选出的两个数相同时,减法和除法只做一次,即只做a-b ,a/b, 不做 b-a,b/a,其中1、3都可以减少冗余计算

调用函数PointGame即可返回表达式结果                                                                                                     本文地址

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<string>
  4 #include<map>
  5 #include<set>
  6 #include<cmath>
  7 #include<ctime>
  8 using namespace std;
  9 
 10 //cards[i]的值是通过表达式expr[i]计算而来
 11 //且expr的最后一个运算操作lastop[i]
 12 bool GameRecur(double cards[], string expr[], char lastop[],
 13                const int cardsNum, const int result)
 14 {
 15     if(cardsNum == 1)
 16     {
 17         if(cards[0] == result)
 18         {
 19             //cout<<expr[0]<<endl;
 20             return true;
 21         }
 22         else return false;
 23     }
 24     //从已有数中任选两个,计算得到中间结果,并且和剩余的数一起存在cards数组的前
 25     //cardsNum-1个位置
 26     map<pair<double,double>,bool> selectedPair;
 27     for(int i = 0; i<cardsNum; i++)
 28     {
 29         for(int k  = i+1; k < cardsNum; k++)
 30         {
 31             if( selectedPair.find(pair<double, double>(cards[i], cards[k]))
 32                != selectedPair.end() || selectedPair.find(pair<double, double>
 33                (cards[k], cards[i])) != selectedPair.end() )
 34                 break;
 35             else
 36             {
 37                 selectedPair[pair<double,double>(cards[i], cards[k])] = 1;
 38                 selectedPair[pair<double,double>(cards[k], cards[i])] = 1;
 39             }
 40             //上面的代码保证选出的数对不重复
 41             double a = cards[i], b = cards[k];
 42             cards[k] = cards[cardsNum-1];
 43             string expra = expr[i], exprb = expr[k];
 44             expr[k] = expr[cardsNum-1];
 45             char lastop_a = lastop[i], lastop_b = lastop[k];
 46             lastop[k] = lastop[cardsNum-1];
 47 
 48             cards[i] = a + b;
 49             expr[i] = expra + '+' + exprb;
 50             lastop[i] = '+';
 51             if(GameRecur(cards, expr, lastop, cardsNum-1, result))
 52                 return true;
 53 
 54             cards[i] = a - b;
 55             if('+' == lastop_b || '-' == lastop_b)
 56                 expr[i] = expra + '-' + '(' + exprb + ')';
 57             else expr[i] = expra + '-' + exprb;
 58             lastop[i] = '-';
 59             if(GameRecur(cards, expr, lastop, cardsNum-1, result))
 60                 return true;
 61 
 62             if(a != b)
 63             {
 64                 cards[i] = b - a;
 65                 if('+' == lastop_a || '-' == lastop_a)
 66                     expr[i] = exprb + '-' + '(' + expra + ')';
 67                 else expr[i] = exprb + '-' + expra;
 68                 lastop[i] = '-';
 69                 if(GameRecur(cards, expr, lastop, cardsNum-1, result))
 70                     return true;
 71             }
 72 
 73             cards[i] = a * b;
 74             if('-' == lastop_a || '+' == lastop_a)
 75                 expr[i] = '(' + expra + ')' + '*';
 76             else expr[i] = expra + '*';
 77             if('*' == lastop_b || ' ' == lastop_b)
 78                 expr[i] += exprb;
 79             else expr[i] += '(' + exprb + ')';
 80             lastop[i] = '*';
 81             if(GameRecur(cards, expr, lastop, cardsNum-1, result))
 82                 return true;
 83 
 84             if(b != 0)
 85             {
 86                 cards[i] = a / b;
 87                 if('-' == lastop_a || '+' == lastop_a)
 88                     expr[i] = '(' + expra + ')' + '/';
 89                 else expr[i] = expra + '/';
 90                 if(' ' == lastop_b)
 91                     expr[i] += exprb;
 92                 else expr[i] += '(' + exprb + ')';
 93                 lastop[i] = '/';
 94                 if(GameRecur(cards, expr, lastop, cardsNum-1, result))
 95                     return true;
 96             }
 97 
 98             if(a != 0 && a!= b)
 99             {
100                 cards[i] = b / a;
101                 if('-' == lastop_b || '+' == lastop_b)
102                     expr[i] = '(' + exprb + ')' + '/';
103                 else expr[i] = exprb + '/';
104                 if(' ' == lastop_a)
105                     expr[i] += expra;
106                 else expr[i] += '(' + expra + ')';
107                 lastop[i] = '/';
108                 if(GameRecur(cards, expr, lastop, cardsNum-1, result))
109                     return true;
110             }
111 
112             //把选出来的两个数放回原位
113             cards[i] = a;
114             cards[k] = b;
115             expr[i] = expra;
116             expr[k] = exprb;
117             lastop[i] = lastop_a;
118             lastop[k] = lastop_b;
119         }
120     }
121     return false;
122 }
123 
124 //cards 输入的牌
125 //cardsNum 牌的数目
126 //result 想要运算得到的结果
127 string PointGame(int cards[], const int cardsNum, const int result)
128 {
129     string expr[cardsNum];
130     char lastop[cardsNum];
131     double cardsCopy[cardsNum];
132     for(int i = 0; i < cardsNum; i++)
133     {
134         char buf[30];
135         sprintf(buf, "%d", cards[i]);
136         expr[i] = buf;
137         lastop[i] = ' ';//表示cardsCopy[i]是不经过任何运算的原始数据
138         cardsCopy[i] = cards[i];
139     }
140     if(GameRecur(cardsCopy, expr, lastop, cardsNum, result))
141         return expr[0];
142     else return "-1";
143 }
View Code

相关文章:

  • 2021-10-12
  • 2021-06-04
  • 2021-07-31
猜你喜欢
  • 2022-12-23
  • 2021-12-31
  • 2021-12-21
  • 2022-12-23
  • 2022-03-05
  • 2022-12-23
相关资源
相似解决方案