题目描述
陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。
输入
包括两行数据。第一行包含10个100到200之间(包括100和200)的整数(以厘米为单位)分别表示10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。第二行只包括一个100到120之间(包含100和120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。
输出
包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。
样例输入
复制
100 200 150 140 129 134 167 198 200 111
110
样例输出
复制
5
问题分析
题目描述陶陶摘苹果的情景:
-
有10个苹果,每个苹果都有不同的高度(100-200厘米)
-
陶陶自己能够到的高度是h厘米(100-120厘米)
-
陶陶有一个30厘米高的板凳,可以增加她的高度
-
需要计算陶陶能摘到多少个苹果(苹果高度 ≤ 陶陶能到的高度)
解决思路
-
输入处理:需要读取两行输入
-
第一行:10个苹果的高度
-
第二行:陶陶的手伸直高度
-
-
计算最大可摘高度:
-
陶陶站在板凳上后的总高度 = 手伸直高度 + 板凳高度
-
-
统计可摘苹果数量:
-
遍历所有苹果高度
-
比较每个苹果高度和最大可摘高度
-
统计符合条件的苹果数量
-
代码实现详解
#include <iostream>
using namespace std;
int main() {
// 1. 存储苹果高度
int apples[10]; // 定义能存储10个整数的数组
// 读取10个苹果的高度
for (int i = 0; i < 10; ++i) {
cin >> apples[i]; // 逐个读取并存入数组
}
// 2. 读取陶陶的手伸直高度
int h;
cin >> h;
// 计算最大可摘高度(手伸直高度 + 板凳高度)
int max_reach = h + 30;
// 3. 统计能摘到的苹果数量
int count = 0; // 初始化计数器
for (int i = 0; i < 10; ++i) {
if (apples[i] <= max_reach) { // 判断苹果是否可摘
count++; // 可摘则计数器加1
}
}
// 4. 输出结果
cout << count << endl;
return 0;
}
关键点说明
-
数组使用:用数组
apples[10]存储10个苹果的高度,方便后续遍历比较 -
高度计算:
max_reach = h + 30准确计算了陶陶的最大可摘高度 -
遍历比较:通过
for循环遍历每个苹果,使用if判断是否可摘 -
计数器:
count变量记录可摘苹果数量,最后输出
示例验证
以样例输入为例:
100 200 150 140 129 134 167 198 200 111
110
计算过程:
-
最大可摘高度:110 + 30 = 140
-
可摘苹果:
-
100 ≤ 140 ✔
-
200 > 140 ✖
-
150 > 140 ✖
-
140 ≤ 140 ✔
-
129 ≤ 140 ✔
-
134 ≤ 140 ✔
-
167 > 140 ✖
-
198 > 140 ✖
-
200 > 140 ✖
-
111 ≤ 140 ✔
-
-
可摘总数:5个
复杂度分析
-
时间复杂度:O(1),因为固定循环10次
-
空间复杂度:O(1),使用固定大小的数组
对于这个看似简单的摘苹果问题,我们可以从多个角度进行更深入的分析和优化。虽然基础解法已经足够高效,但我们可以探讨以下几个进阶方向:
1. 算法优化分析
int count = 0;
for(int i=0; i<10; ++i){
count += (apples[i] <= max_reach); // 布尔值隐式转换为1或0
}
基础解法的时间复杂度已经是O(1)(固定10次循环),看似没有优化空间。但我们可以考虑:
位运算优化(虽然对性能提升不大,但可作为思维训练):
并行计算思想(现代CPU支持SIMD):
// 需要编译器支持SIMD指令
__m128i v_max = _mm_set1_epi32(max_reach);
__m128i v_apples = _mm_loadu_si128((__m128i*)apples);
__m128i cmp = _mm_cmple_epi32(v_apples, v_max);
count += _mm_popcnt_u32(_mm_movemask_epi8(cmp))/4;
2. 输入验证增强
增加鲁棒性检查:
// 验证苹果高度范围
for(int i=0; i<10; ++i){
if(apples[i]<100 || apples[i]>200){
cerr << "苹果高度超出范围!" << endl;
return 1;
}
}
// 验证陶陶高度范围
if(h<100 || h>120){
cerr << "陶陶高度超出范围!" << endl;
return 1;
}
3. 数学建模
可以建立数学模型:
设苹果高度集合为A = {a₁, a₂, ..., a₁₀}
陶陶可摘高度为H = h + 30
解为集合S = {a ∈ A | a ≤ H}的基数
6. 可视化分析
可以绘制高度分布图:
# 假设用Python可视化
import matplotlib.pyplot as plt
plt.bar(range(10), apples)
plt.axhline(y=max_reach, color='r')
plt.show()
最优解法推荐
对于本题,最优解仍然是基础解法,因为:
-
问题规模极小(n=10)
-
输入范围严格受限
-
不需要复杂的数据结构
-
代码可读性最重要
最终建议的实现:
#include <iostream>
using namespace std;
int main() {
int apples[10];
for(int i=0; i<10; ++i){
cin >> apples[i];
}
int h, count=0;
cin >> h;
const int max_reach = h + 30;
for(int a : apples){
count += (a <= max_reach);
}
cout << count << endl;
return 0;
}
这个版本:
-
使用范围for循环提高可读性
-
使用const明确最大高度不变
-
保持简洁高效的特性
-
易于理解和维护
对于编程初学者来说,理解这个基础解法并能够正确实现,比追求各种"高级"优化更有实际意义。当遇到更大规模或更复杂的问题时,再考虑更高级的优化技术更为合适。
147

被折叠的 条评论
为什么被折叠?



