酷爱游戏的小明,最喜欢就是卡牌类型游戏24点。
游戏的规则是:你会被分配抽取N张扑克牌,分别从A-K,其中规定牌面为A的牌,其数值为1点;牌面为J、Q、K的牌,其数值分别为11、12、13点;数字牌的点数与其所表示的数字一致。现在你可以通过移动这N张牌的任意次序,并在两两之间插入四种运算符号+、-、*、\(注:除法在这里仅考虑整除的情况,例如3/2=1,4/2=2)。经过上述操作后,我们按照运算顺序计算表达式的结果,如果结果恰好凑成24点,则游戏取得胜利。
现在,你被要求和小明进行一局游戏,因此你需要实现一个程序来帮助你解决如下问题:
当你读入N张牌和其对应的数值,你有多少种方法能够恰好凑出24点,并且要输出每种方法的具体情况。
(我们规定:两种方法不同,当且仅当对应的两个表达式字符串不同。)
例如:给出的5张牌为1,2,3(1),3(2),5,其中有两个数值3的牌,为了加以区分,我们暂时用下标来进行区分,但在实际测试数据中不会有任何区分。此时,方案1+2*3(1)*3(2)+5和方案1+2*3(2)*3(1)+5是完全相同的解,在结果中只需要输出一次。
输入
输入包括两行,第一行一个整数N,代表卡牌数量,保证N<=6
第二行输入N个整数,依次表示卡牌的数值。
输出
输出每种可能的方案,按照字符串格式输出,计算数与符号之间不需要加空格。
最后一行输出一个整数,表示可行的解的数量。
样例输入
4
10 2 13 6
样例输出
6+10/2+13
6+13+10/2
10/2+6+13
10/2+13+6
13+6+10/2
13+10/2+6
6
提示:
本题考查的重点为:表达式求值问题
常见的解法有两种,一种是使用递归实现的主符号法、一种是使用栈进行模拟,转成逆波兰表达式进行计算。两种方法都非常的经典,效率较高,请各位同学自行学习以上两种方法,并选择其中一种方法来实现这道题目。
本题目采用Special Judge方式进行评测,因此在输出方案时,不需要考虑顺序的问题。输出顺序与样例不一致不会使程序产生错误。
参考代码:使用bool Search(int n) 递归函数
#include
#include
#include
using namespace std;
const double PRECISION = 1E-6;
const int COUNT_OF_NUMBER = 4;
const int NUMBER_TO_BE_CAL = 24;
double number[COUNT_OF_NUMBER];
string expression[COUNT_OF_NUMBER];
bool Search(int n)
{
if (n == 1) {
if ( fabs(number[0] - NUMBER_TO_BE_CAL) < PRECISION ) {
cout << expression[0] << endl;
return true;
} else {
return false;
}
}
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
double a, b;
string expa, expb;
a = number[i];
b = number[j];
number[j] = number[n - 1];
expa = expression[i];
expb = expression[j];
expression[j] = expression[n - 1];
expression[i] = '(' + expa + '+' + expb + ')';
number[i] = a + b;
if ( Search(n - 1) ) return true;
expression[i] = '(' + expa + '-' + expb + ')';
number[i] = a - b;
if ( Search(n - 1) ) return true;
expression[i] = '(' + expb + '-' + expa + ')';
number[i] = b - a;
if ( Search(n - 1) ) return true;
expression[i] = '(' + expa + '*' + expb + ')';
number[i] = a * b;
if ( Search(n - 1) ) return true;
if (b != 0) {
expression[i] = '(' + expa + '/' + expb + ')';
number[i] = a / b;
if ( Search(n - 1) ) return true;
}
if (a != 0) {
expression[i] = '(' + expb + '/' + expa + ')';
number[i] = b / a;
if ( Search(n - 1) ) return true;
}
number[i] = a;
number[j] = b;
expression[i] = expa;
expression[j] = expb;
}
}
return false;
}
void main()
{
for (int i = 0; i < COUNT_OF_NUMBER; i++) {
char buffer[20];
int x;
cin >> x;
number[i] = x;
itoa(x, buffer, 10);
expression[i] = buffer;
}
if ( Search(COUNT_OF_NUMBER) ) {
cout << "Success." << endl;
} else {
cout << "Fail." << endl;
}
}
如有帮助,望采纳
#include <iostream>
#include <string>
using namespace std;
int mark_int[4] = { 1,2,3,4 };
string mark_char = "+-*/";
double cal(double a, int m, double b)
{
switch (m)
{
case 1: return a + b;
case 2: return a - b;
case 3: return a * b;
case 4: 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 == 24)
{
cout << "(((" << a << mark_char[m1 - 1] << b << ")" << mark_char[m2 - 1] << c << ")" << mark_char[m3 - 1] << d << ")" << endl;
return 1;
}
return 0;
}
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 == 24)
{
cout << "((" << a << mark_char[m1 - 1] << "(" << b << mark_char[m2 - 1] << c << "))" << mark_char[m3 - 1] << d << ")" << endl;
return 1;
}
return 0;
}
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 == 24)
{
cout << "(" << a << mark_char[m1 - 1] << "((" << b << mark_char[m2 - 1] << c << ")" << mark_char[m3 - 1] << d << "))" << endl;
return 1;
}
return 0;
}
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 == 24)
{
cout << "(" << a << mark_char[m1 - 1] << "(" << b << mark_char[m2 - 1] << "(" << c << mark_char[m3 - 1] << d << ")))" << endl;
return 1;
}
return 0;
}
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 == 24)
{
cout << "((" << a << mark_char[m1 - 1] << b << ")" << mark_char[m2 - 1] << "(" << c << mark_char[m3 - 1] << d << "))" << endl;
return 1;
}
return 0;
}
bool all_cal(int a, int b, int c, int d)
{
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++)
for (int k = 1; k <= 4; 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 1;
}
return 0;
}
bool judge(int a, int b, int c, int d)
{
int all[24][4] = {
{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 = 0; i < 24; i++)
{
if (all_cal(all[i][0], all[i][1], all[i][2], all[i][3]))
return 1;
}
return 0;
}
int main()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
if (!judge(a, b, c, d))
cout << "凑不成24点" << endl;
}
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
string s;
int fac() {
int result = 0;
char c = s.back();
while (isdigit(c)) {
result = 10 * result + c - '0';
s.pop_back();
c = s.back();
}
return result;
}
int term() {
int result = fac();
while (true) {
char op = s.back();
if (op == '*' || op == '/') {
s.pop_back();
int value = fac();
if (op == '*') {
result *= value;
}
else
result /= value;
}
else
break;
}
return result;
}
int exp() {
int result = term();
while (true) {
char op = s.back();
if (op == '+' || op == '-') {
s.pop_back();
int value = term();
if (op == '+') {
result += value;
}
else
result -= value;
}
else
break;
}
return result;
}
int a[7], n;
char op[4] = { '*', '/', '+', '-' };
vector<string> ans;
map<string, bool> mp;
void dfs(int pos, string res) {
string t;
for (int i = 0; i < 4; i++) {
t = res;
t += op[i];
t += to_string(a[pos]);
if (pos == n) {
s = t;
reverse(begin(s), end(s));
if (exp() == 24) {
if (!mp[t]) {
ans.push_back(t);
mp[t] = 1;
}
}
}
else
dfs(pos + 1, t);
}
if (pos == n)
return;
}
int main() {
int x;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + n + 1);
for (int j = 0; j <= n; j++) {
if (n > 0) x = 0;
else x = 1;
}
string res;
while (x > 0) {
if (n > 0) x--;
}
res += to_string(a[1]);
dfs(2, res);
while (next_permutation(a + 1, a + n + 1)) {
string res;
res += to_string(a[1]);
dfs(2, res);
}
for (auto i : ans)
cout << i << endl;
cout << ans.size() << endl;
return 0;
}