B4411 和 B3836 C++ 题解: GESP 题目,考察基础的循环、条件判断和枚举算法。
题目1: B4411 - 优美的数字
题目链接: https://www.luogu.com.cn/problem/B4411
题目描述摘要: 统计不超过正整数 n 的所有数位都相同的“优美数字”的个数。“优美数字”定义为在十进制下所有数位都相同的正整数,例如 6、99、4444。n 的范围是 1 ≤ n ≤ 2025。
解题思路:
由于 n 的最大值为 2025,数字最多只有4位。我们可以枚举所有可能的“优美数字”:
- 外层循环枚举数字
d(从 1 到 9),即构成优美数字的重复数字。 - 内层循环枚举这个数字的位数
len(从 1 到 4,因为 2025 是四位数)。 - 在内层循环中,通过循环构造出位数为
len、每一位都是d的数字。 - 将构造出的数字与
n比较,如果不超过n,则方案数加一。
这种方法直接枚举了所有可能的优美数字,思路清晰,且在给定的数据范围下效率足够。
总结与要点:
- 核心思路:本题的核心是判断一个数字的所有数位是否相同。
- 常见解法:除了上述的“构造枚举法”,另一种通用性更强的解法是“数位分解”。对于一个给定的正整数,可以通过不断
% 10取出其个位数,再通过/ 10去掉个位数,将取出的每一位数字与首位(或上一位)进行比较,若全部相同则为优美数字。这种方法不依赖于n的位数限制。
C++ 代码 (构造枚举法):
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int count = 0; // 用于计数优美数字的数量
// 枚举构成优美数字的重复数字d (1~9)
for (int d = 1; d <= 9; d++) {
int num = 0;
// 枚举这个优美数字的位数len (1~4)
for (int len = 1; len <= 4; len++) {
// 构造一个位数为len,每一位都是d的数字
num = num * 10 + d;
// 如果构造出的数字不超过n,则是一个有效的优美数字
if (num <= n) {
count++;
}
}
}
cout << count << endl;
return 0;
}
题目2: B3836 - 扩展百鸡问题
题目链接: https://www.luogu.com.cn/problem/B3836
题目描述摘要: 公鸡每只 x 元,母鸡每只 y 元,小鸡 z 只 1 元。现在有 n 元,要买 m 只鸡(公鸡、母鸡、小鸡都必须有),问有多少种购买方案。数据约定:1 ≤ x, y, z ≤ 10, 1 ≤ n, m ≤ 1000。这是对古典“百鸡问题”的扩展。
解题思路:
这是一个三元一次方程求整数解的问题,约束条件如下:
公鸡数 * x + 母鸡数 * y + 小鸡数 / z = n (其中小鸡数必须是 z 的倍数)
公鸡数 + 母鸡数 + 小鸡数 = m
由于数据范围较小(m ≤ 1000),最直接的思路是使用两重循环枚举公鸡和母鸡的数量,小鸡的数量可以通过总鸡数 m 计算得出,然后验证是否满足总金额 n 的条件以及小鸡数量是 z 的倍数。此方法时间复杂度为 O(m²),在给定数据范围内完全可行。
总结与要点:
- 核心算法:本题的核心是枚举算法与条件判断。
- 关键条件:处理“每 z 只小鸡 1 元”这个条件是本题的关键点。在枚举出公鸡和母鸡数量后,计算出的小鸡数量
k必须是z的整数倍(即k % z == 0),其对应的花费才能计算为k / z元。否则,该方案不合法。这是与经典百鸡问题最重要的扩展点。
C++ 代码:
#include <iostream>
using namespace std;
int main() {
int x, y, z, n, m;
cin >> x >> y >> z >> n >> m;
int cnt = 0; // 用于记录方案数
// 枚举公鸡的数量 i
for (int i = 0; i <= m; i++) {
// 枚举母鸡的数量 j
for (int j = 0; j <= m - i; j++) {
int k = m - i - j; // 计算小鸡的数量 k
// 方案有效的条件:
// 1. 小鸡数量 k 必须是非负数(循环条件已保证)
// 2. 小鸡数量必须是 z 的倍数(因为 z 只一起卖)
// 3. 总价格必须恰好等于 n 元
if (k % z == 0 && i * x + j * y + k / z == n) {
cnt++;
}
}
}
cout << cnt << endl;
return 0;
}

浙公网安备 33010602011771号