跳过并跳转到主要内容
BigO

百鸡问题

求解扩展版的“百鸡问题”,即已知公鸡每只 x 元、母鸡每只 y 元、小鸡每 z 只 1 元,求用 n 元钱恰好购买 m 只鸡的所有可行组合方案数。

GESP1分钟阅读

  1. 变量定义:
    • 设购买公鸡 aa 只(每只 xx 元)、母鸡 bb 只(每只 yy 元)、小鸡 cc 只(每 zz 只 11 元)。
    • 需要满足两个条件:
      1. 总数量:a+b+c=ma + b + c = m
      2. 总金额:a×x+b×y+cz=na \times x + b \times y + \frac{c}{z} = n
  2. 枚举优化:
    • 范围限制:数据范围 n,m≤1000n, m \le 1000,且 x,y,z≥1x, y, z \ge 1。如果使用三重循环枚举 a,b,ca, b, c 会超时(O(m3)O(m^3))。
    • 双重循环优化:由于 a+b+c=ma + b + c = m,只需要通过两重循环枚举公鸡数量 aa 和母鸡数量 bb,即可直接算出小鸡数量 c=m−a−bc = m - a - b。这样时间复杂度降为 O(m2)O(m^2),在 1.00s1.00\text{s} 内可以轻松通过。
  3. 判定条件:
    • 小鸡数量 cc 必须是非负整数:c≥0c \ge 0。
    • 小鸡必须能按套(每 zz 只 11 元)整买:即 cc 必须是 zz 的倍数(c % z == 0)。
    • 总花费必须刚好等于 nn:a * x + b * y + c / z == n。

#include <iostream>
using namespace std;
int main() {
// 提高输入输出效率
ios::sync_with_stdio(false);
cin.tie(nullptr);
int x, y, z, n, m;
if (!(cin >> x >> y >> z >> n >> m)) return 0;
int ans = 0; // 记录方案数
// 枚举公鸡数量 a
for (int a = 0; a * x <= n && a <= m; ++a) {
// 枚举母鸡数量 b
for (int b = 0; a * x + b * y <= n && a + b <= m; ++b) {
int c = m - a - b; // 计算小鸡数量
// 验证小鸡数量是否能被 z 整除,且总钱数刚好为 n
if (c % z == 0 && (a * x + b * y + c / z == n)) {
ans++;
}
}
}
cout << ans << "\n";
return 0;
}

© 2026 三七开 · 一方通行,只管向前。

旅途由 Astro 驱动 · 主题 Chirping Astro