1236: 陶陶摘苹果

题目描述

陶陶家的院子里有一棵苹果树,每到秋天树上就会结出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

问题分析

题目描述陶陶摘苹果的情景:

  1. 有10个苹果,每个苹果都有不同的高度(100-200厘米)

  2. 陶陶自己能够到的高度是h厘米(100-120厘米)

  3. 陶陶有一个30厘米高的板凳,可以增加她的高度

  4. 需要计算陶陶能摘到多少个苹果(苹果高度 ≤ 陶陶能到的高度)

解决思路

  1. 输入处理:需要读取两行输入

    • 第一行:10个苹果的高度

    • 第二行:陶陶的手伸直高度

  2. 计算最大可摘高度

    • 陶陶站在板凳上后的总高度 = 手伸直高度 + 板凳高度

  3. 统计可摘苹果数量

    • 遍历所有苹果高度

    • 比较每个苹果高度和最大可摘高度

    • 统计符合条件的苹果数量

代码实现详解

#include 
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;
}

关键点说明

  1. 数组使用:用数组apples[10]存储10个苹果的高度,方便后续遍历比较

  2. 高度计算max_reach = h + 30准确计算了陶陶的最大可摘高度

  3. 遍历比较:通过for循环遍历每个苹果,使用if判断是否可摘

  4. 计数器count变量记录可摘苹果数量,最后输出

示例验证

以样例输入为例:

100 200 150 140 129 134 167 198 200 111
110

计算过程:

  1. 最大可摘高度:110 + 30 = 140

  2. 可摘苹果:

    • 100 ≤ 140 ✔

    • 200 > 140 ✖

    • 150 > 140 ✖

    • 140 ≤ 140 ✔

    • 129 ≤ 140 ✔

    • 134 ≤ 140 ✔

    • 167 > 140 ✖

    • 198 > 140 ✖

    • 200 > 140 ✖

    • 111 ≤ 140 ✔

  3. 可摘总数: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()

最优解法推荐

对于本题,最优解仍然是基础解法,因为:

  1. 问题规模极小(n=10)

  2. 输入范围严格受限

  3. 不需要复杂的数据结构

  4. 代码可读性最重要

最终建议的实现:

#include 
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明确最大高度不变

  • 保持简洁高效的特性

  • 易于理解和维护

对于编程初学者来说,理解这个基础解法并能够正确实现,比追求各种"高级"优化更有实际意义。当遇到更大规模或更复杂的问题时,再考虑更高级的优化技术更为合适。

你可能感兴趣的:(算法)