1. 项目背景与问题定义
这道源自马克思手稿的数学题,本质上是一个典型的三元一次方程组问题。题目描述为:30人(包含男人、女人和小孩)在饭馆共消费50先令,已知男人每人花3先令,女人每人花2先令,小孩每人花1先令。需要求出所有可能的组合方案。
在实际教学中,这类问题常被用作编程入门练习,因为它同时考察了:
- 基础算法设计能力(穷举法的实现)
- 条件判断与循环结构的运用
- 数学建模思维(将文字描述转化为方程)
注意:原始问题中的"先令"是英国旧货币单位,但在编程实现中完全可以用整数类型处理,无需考虑浮点数精度问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 程序设计与实现思路
2.1 数学模型建立
首先将问题转化为数学表达式:
code复制设男人数量为x,女人为y,小孩为z
则有:
(1) x + y + z = 30
(2) 3x + 2y + z = 50
通过数学推导可以消元简化:
code复制(2)-(1)得:2x + y = 20 ⇒ y = 20 - 2x
将y代入(1):z = 30 - x - (20 - 2x) = 10 + x
2.2 算法选择
最直接的解法是三重循环穷举所有可能组合:
c复制for(int x=0; x<=30; x++){
for(int y=0; y<=30; y++){
for(int z=0; z<=30; z++){
if(x+y+z==30 && 3*x+2*y+z==50){
printf("Solution: %d men, %d women, %d children\n",x,y,z);
}
}
}
}
但经过数学优化后,只需单层循环:
c复制for(int x=0; x<=10; x++){ // 由y=20-2x≥0得出x≤10
int y = 20 - 2*x;
int z = 10 + x;
printf("Solution: %d men, %d women, %d children\n",x,y,z);
}
2.3 代码优化策略
- 循环边界优化:原始三重循环需要30^3=27000次迭代,优化后最多11次
- 变量命名规范:使用men/women/children代替x/y/z增强可读性
- 输入输出扩展:可增加用户输入总人数和总金额的功能
- 错误处理:添加无解情况的判断
3. 完整实现代码
c复制#include <stdio.h>
void solveMarxProblem(int totalPeople, int totalMoney) {
int found = 0;
printf("Possible combinations for %d people spending %d shillings:\n",
totalPeople, totalMoney);
for(int men=0; men<=totalPeople; men++){
for(int women=0; women<=totalPeople-men; women++){
int children = totalPeople - men - women;
if(3*men + 2*women + children == totalMoney){
printf("- %d men, %d women, %d children\n",
men, women, children);
found = 1;
}
}
}
if(!found){
printf("No valid combination found.\n");
}
}
int main() {
// 原始问题求解
solveMarxProblem(30, 50);
// 扩展:用户自定义输入
