24点代码详解

24点代码详解 未完成代码#includeiostream #includevector using namespace std; bool judge(vectorintnums) { for (int i 0;i 3;i) { for (int j 0;j 3;j) { if (j i) continue; } } return true; } int main() { vectorintnums(4); for (int i 0;i 4;i) cin nums[i]; while (nums[0] ! 0 nums[1] ! 0 nums[2] ! 0 nums[3] ! 0) { if (judge(nums)) cout YES endl; else cout NO endl; for (int i 0;i 3;i) cin nums[i]; } return 0; }根据24点游戏的规则我们需要检查4个数字能否通过加减乘除运算得到24。以下是完善后的代码#includeiostream #includevector #includecmath using namespace std; // 计算两个数字的运算结果 vectordouble calculate(double a, double b) { vectordouble res; res.push_back(a b); res.push_back(a - b); res.push_back(b - a); res.push_back(a * b); if (b ! 0) res.push_back(a / b); if (a ! 0) res.push_back(b / a); return res; } bool dfs(vectordouble nums) { // 如果只剩一个数字判断是否接近24考虑浮点数精度 if (nums.size() 1) { return fabs(nums[0] - 24) 1e-6; } // 选择两个不同的数字进行运算 for (int i 0; i nums.size(); i) { for (int j 0; j nums.size(); j) { if (i j) continue; vectordouble next; // 将未参与运算的数字加入next for (int k 0; k nums.size(); k) { if (k ! i k ! j) { next.push_back(nums[k]); } } // 尝试所有可能的运算结果 vectordouble results calculate(nums[i], nums[j]); for (double res : results) { next.push_back(res); if (dfs(next)) return true; next.pop_back(); } } } return false; } bool judge(vectorint nums) { // 将int转换为double进行浮点数运算 vectordouble doubleNums(nums.begin(), nums.end()); return dfs(doubleNums); } int main() { vectorint nums(4); for (int i 0; i 4; i) cin nums[i]; // 修改循环条件4个数字都为0时结束 while (nums[0] ! 0 || nums[1] ! 0 || nums[2] ! 0 || nums[3] ! 0) { if (judge(nums)) cout YES endl; else cout NO endl; // 重新输入4个数字 for (int i 0; i 4; i) cin nums[i]; } return 0; }主要改进点修改了循环条件原代码的条件nums[0] ! 0 nums[1] ! 0 nums[2] ! 0 nums[3] ! 0会导致在任意一个数字为0时就退出应改为||逻辑只有4个数字都为0时才退出。完善了judge函数实现了24点游戏的DFS算法每次选择两个不同的数字进行运算支持加减乘除运算注意除法需要检查除数不为0考虑了交换律减法和除法使用浮点数运算并设置精度容差增加了必要的头文件#includecmath用于fabs函数。修正了输入逻辑每次循环需要输入4个数字而不是3个。这个程序可以判断任意4个1-13之间的数字能否通过四则运算得到24。24点游戏C代码详细解释1. 头文件包含和命名空间#includeiostream // 包含输入输出流功能cin, cout #includevector // 包含向量容器动态数组 #includecmath // 包含数学函数fabs求绝对值 using namespace std; // 使用标准命名空间避免写std::2. 辅助计算函数// 计算两个数字的所有可能运算结果 vectordouble calculate(double a, double b) { vectordouble res; // 创建一个double类型的向量存储结果 res.push_back(a b); // 加法 res.push_back(a - b); // 减法 a-b res.push_back(b - a); // 减法 b-a考虑交换律 res.push_back(a * b); // 乘法 if (b ! 0) res.push_back(a / b); // 除法 a÷b确保除数不为0 if (a ! 0) res.push_back(b / a); // 除法 b÷a考虑交换律 return res; // 返回所有可能的结果 }作用计算两个数字的所有可能运算组合参数a, b 为两个待运算的数字返回包含6种可能结果的向量除法最多2种3. 深度优先搜索DFS函数bool dfs(vectordouble nums) { // 递归终止条件只剩一个数字 if (nums.size() 1) { // 判断这个数字是否等于24考虑浮点数精度误差 return fabs(nums[0] - 24) 1e-6; } // 选择两个不同的数字进行运算 for (int i 0; i nums.size(); i) { for (int j 0; j nums.size(); j) { if (i j) continue; // 跳过同一个数字 vectordouble next; // 创建下一轮计算的数字列表 // 将未参与运算的数字加入next for (int k 0; k nums.size(); k) { if (k ! i k ! j) { // 不是被选中的两个数字 next.push_back(nums[k]); } } // 尝试所有可能的运算结果 vectordouble results calculate(nums[i], nums[j]); for (double res : results) { // 遍历每个运算结果 next.push_back(res); // 将结果加入下一轮 if (dfs(next)) return true; // 递归搜索 next.pop_back(); // 回溯移除结果 } } } return false; // 所有尝试都失败 }递归思路每次从数字中选两个进行运算用结果替换原来的两个数字回溯尝试失败后撤销选择尝试其他可能性1e-6浮点数比较的精度阈值因为浮点数运算可能有微小误差4. 主判断函数bool judge(vectorint nums) { // 将int转换为double进行浮点数运算 vectordouble doubleNums(nums.begin(), nums.end()); return dfs(doubleNums); }作用接口函数将整数转换为浮点数然后调用DFS为什么用double除法可能产生小数5. 主函数int main() { vectorint nums(4); // 创建包含4个int的向量 // 输入第一组4个数字 for (int i 0; i 4; i) cin nums[i]; // 循环处理直到输入四个0 while (nums[0] ! 0 || nums[1] ! 0 || nums[2] ! 0 || nums[3] ! 0) { // 判断是否能得到24 if (judge(nums)) cout YES endl; // 可以 else cout NO endl; // 不可以 // 输入下一组4个数字 for (int i 0; i 4; i) cin nums[i]; } return 0; // 程序正常结束 }6. 关键修改说明// 原代码问题 while (nums[0] ! 0 nums[1] ! 0 nums[2] ! 0 nums[3] ! 0) // 这个条件任意一个数字不为0就继续 // 当输入 0 1 2 3 时第一个是0条件为假循环结束 // 修改后 while (nums[0] ! 0 || nums[1] ! 0 || nums[2] ! 0 || nums[3] ! 0) // 正确条件四个数字不全为0才继续 // 只有输入 0 0 0 0 时所有数字都为0条件为假循环结束7. 算法复杂度分析时间复杂度O(4! × 4³ × 6²) ≈ 常数级别4! 种数字排列每次从n个数字中选2个最多6种运算空间复杂度O(4) 递归深度最大为4