#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define EPS 1e-6
#define TARGET 24
// 四则运算计算
double calc(double a, double b, int op)
{
switch(op)
{
case 0: return a + b;
case 1: return a - b;
case 2: return a * b;
case 3:
if(fabs(b) < EPS) return -999999; // 除零非法
return a / b;
default: return 0;
}
}
// 运算符转字符
char getOp(int op)
{
switch(op)
{
case 0: return '+';
case 1: return '-';
case 2: return '*';
case 3: return '/';
default: return ' ';
}
}
// 递归全排列(4个数)
int vis[4];
int num[4];
int buf[4];
int found = 0;
// 枚举3个运算符 op1 op2 op3
void dfsOp(int op1, int op2, int op3)
{
double a = buf[0], b = buf[1], c = buf[2], d = buf[3];
char o1 = getOp(op1), o2 = getOp(op2), o3 = getOp(op3);
double r;
// 结构1: ((a o1 b) o2 c) o3 d
r = calc(calc(calc(a,b,op1), c, op2), d, op3);
if(fabs(r - TARGET) < EPS)
{
printf("((%d%c%d)%c%d)%c%d = 24\n", (int)a,o1,(int)b,o2,(int)c,o3,(int)d);
found = 1;
}
// 结构2: (a o1 (b o2 c)) o3 d
r = calc(calc(a, calc(b,c,op2), op1), d, op3);
if(fabs(r - TARGET) < EPS)
{
printf("(%d%c(%d%c%d))%c%d = 24\n", (int)a,o1,(int)b,o2,(int)c,o3,(int)d);
found = 1;
}
// 结构3: a o1 ((b o2 c) o3 d)
r = calc(a, calc(calc(b,c,op2), d, op3), op1);
if(fabs(r - TARGET) < EPS)
{
printf("%d%c((%d%c%d)%c%d) = 24\n", (int)a,o1,(int)b,o2,(int)c,o3,(int)d);
found = 1;
}
// 结构4: a o1 (b o2 (c o3 d))
r = calc(a, calc(b, calc(c,d,op3), op2), op1);
if(fabs(r - TARGET) < EPS)
{
printf("%d%c(%d%c(%d%c%d)) = 24\n", (int)a,o1,(int)b,o2,(int)c,o3,(int)d);
found = 1;
}
// 结构5: (a o1 b) o2 (c o3 d)
r = calc(calc(a,b,op1), calc(c,d,op3), op2);
if(fabs(r - TARGET) < EPS)
{
printf("(%d%c%d)%c(%d%c%d) = 24\n", (int)a,o1,(int)b,o2,(int)c,o3,(int)d);
found = 1;
}
}
// 枚举三组运算符组合 0+ 1- 2* 3/
void enumOp()
{
int o1,o2,o3;
for(o1=0;o1<4;o1++)
for(o2=0;o2<4;o2++)
for(o3=0;o3<4;o3++)
dfsOp(o1,o2,o3);
}
// 回溯生成4数字全排列
void dfsNum(int step)
{
int i;
if(step == 4)
{
enumOp();
return;
}
for(i=0;i<4;i++)
{
if(!vis[i])
{
vis[i] = 1;
buf[step] = num[i];
dfsNum(step+1);
vis[i] = 0;
}
}
}
int main()
{
int i;
printf("==== C语言24点计算器 ====\n");
printf("请输入4个数字(空格隔开): ");
for(i=0;i<4;i++)
{
scanf("%d", &num[i]);
}
printf("========================\n");
// 初始化标记
for(i=0;i<4;i++) vis[i] = 0;
found = 0;
dfsNum(0);
if(!found)
{
printf("该组数字无法算出24点!\n");
}
return 0;
}
#include <iostream>
#include <vector>
#include <set>
#include <cmath>
#include <iomanip>
using namespace std;
const double EPS = 1e-6;
const int TARGET = 24;
// 运算符:0+ 1- 2* 3/
const char opChar[] = {'+', '-', '*', '/'};
// 四则运算函数
double calculate(double a, double b, int op)
{
switch (op)
{
case 0: return a + b;
case 1: return a - b;
case 2: return a * b;
case 3:
if (fabs(b) < EPS) return -9999999; // 除零直接返回非法值
return a / b;
default: return 0;
}
}
// 遍历5种括号结构,验证是否等于24,存入结果集合去重
void checkAllFormat(double n1, double n2, double n3, double n4, int o1, int o2, int o3, set<string>& res)
{
char c1 = opChar[o1], c2 = opChar[o2], c3 = opChar[o3];
double val;
// 结构1: ((a o1 b) o2 c) o3 d
val = calculate(calculate(calculate(n1, n2, o1), n3, o2), n4, o3);
if (fabs(val - TARGET) < EPS)
{
string s = "((" + to_string((int)n1) + c1 + to_string((int)n2) + ")" + c2 + to_string((int)n3) + ")" + c3 + to_string((int)n4);
res.insert(s);
}
// 结构2: (a o1 (b o2 c)) o3 d
val = calculate(calculate(n1, calculate(n2, n3, o2), o1), n4, o3);
if (fabs(val - TARGET) < EPS)
{
string s = "(" + to_string((int)n1) + c1 + "(" + to_string((int)n2) + c2 + to_string((int)n3) + "))" + c3 + to_string((int)n4);
res.insert(s);
}
// 结构3: a o1 ((b o2 c) o3 d)
val = calculate(n1, calculate(calculate(n2, n3, o2), n4, o3), o1);
if (fabs(val - TARGET) < EPS)
{
string s = to_string((int)n1) + c1 + "((" + to_string((int)n2) + c2 + to_string((int)n3) + ")" + c3 + to_string((int)n4) + ")";
res.insert(s);
}
// 结构4: a o1 (b o2 (c o3 d))
val = calculate(n1, calculate(n2, calculate(n3, n4, o3), o2), o1);
if (fabs(val - TARGET) < EPS)
{
string s = to_string((int)n1) + c1 + "(" + to_string((int)n2) + c2 + "(" + to_string((int)n3) + c3 + to_string((int)n4) + "))";
res.insert(s);
}
// 结构5: (a o1 b) o2 (c o3 d)
val = calculate(calculate(n1, n2, o1), calculate(n3, n4, o3), o2);
if (fabs(val - TARGET) < EPS)
{
string s = "(" + to_string((int)n1) + c1 + to_string((int)n2) + ")" + c2 + "(" + to_string((int)n3) + c3 + to_string((int)n4) + ")";
res.insert(s);
}
}
// 枚举3个运算符组合
void enumOperator(vector<double> nums, set<string>& ansSet)
{
for (int o1 = 0; o1 < 4; o1++)
for (int o2 = 0; o2 < 4; o2++)
for (int o3 = 0; o3 < 4; o3++)
checkAllFormat(nums[0], nums[1], nums[2], nums[3], o1, o2, o3, ansSet);
}
// 回溯生成4个数全排列
void permute(vector<int>& src, vector<double>& cur, vector<bool>& vis, set<string>& ans)
{
if (cur.size() == 4)
{
enumOperator(cur, ans);
return;
}
for (int i = 0; i < 4; i++)
{
if (!vis[i])
{
vis[i] = true;
cur.push_back((double)src[i]);
permute(src, cur, vis, ans);
cur.pop_back();
vis[i] = false;
}
}
}
int main()
{
cout << "==== C++ 24点计算器 ====" << endl;
vector<int> num(4);
cout << "请输入4个数字,空格分隔:";
for (int i = 0; i < 4; i++)
cin >> num[i];
set<string> answer;
vector<double> temp;
vector<bool> used(4, false);
permute(num, temp, used, answer);
cout << "========================" << endl;
if (answer.empty())
{
cout << "该组数字无法计算出24点!" << endl;
}
else
{
cout << "共找到 " << answer.size() << " 种解法:" << endl;
for (auto& expr : answer)
cout << expr << " = 24" << endl;
}
return 0;
}