【2025年莆田市第五期C++专项第三轮选拔真题(小学组)】发喜糖

【2025年莆田市第五期C++专项第三轮选拔真题(小学组)】发喜糖

发喜糖

一场隆重的巨人族婚礼正在进行。

喜庆的节日自然少不了发喜糖环节。

现在有n 个巨人站成一排等着发喜糖,每个巨人都有一个身高值(整数)。

身材高的巨人总是有优越感,所以发的喜糖不能比旁边矮的巨人少。

于是主人便定了以下规则发喜糖:

  • 每个巨人至少能分到 1 个糖果。
  • 相邻两个巨人身高更高的会获得更多的果糖。

按以上规则给每个巨人发果糖,请统计下 最少的果糖数目

输入

输入有两行。

第一行有一个整数n.

第二行有n个整数 h i h_i hi,分别表示n个巨人的身高

输出

输出一个整数,表示最少得果糖数目。

输入样例一:

3
1 0 2 

输出样例一:

5

输入样例二:

3
1 2 2

输出样例二:

3

样例一解释:分发2、1、2 颗

样例二解释:分发 1、2、1 颗

数据范围:

10 % 10 \% 10%的数据: 1 ≤ n ≤ 100 1 \leq n \leq 100 1n100且身高具有单调性(递增或者递减)

40 % 40 \% 40%的数据: 1 ≤ n ≤ 10000 , h i ≤ 10000 1 \leq n \leq 10000 ,h_i \leq 10000 1n10000hi10000

100 % 100 \% 100%的数据: 1 ≤ n ≤ 500000 , h i ≤ 1000000 1 \leq n \leq 500000 , h_i \leq 1000000 1n500000,hi1000000

问题理解

这个问题要求我们按照特定规则给一排巨人分发喜糖。规则如下:

  1. 每个巨人至少分到1个糖果
  2. 相邻两个巨人中,身高更高的必须获得更多的糖果
    我们需要找到满足这些条件的最少糖果总数。

解题思路

这个问题可以通过两次遍历数组来解决:

  1. 从左到右遍历:确保每个巨人比左边邻居高时,糖果数也比左边多
  2. 从右到左遍历:确保每个巨人比右边邻居高时,糖果数也比右边多
    这种方法类似于经典的"糖果分配"问题,通过两次遍历可以保证所有相邻关系都满足条件。

代码实现

#include <iostream>
using namespace std;

typedef long long ll;
const int MAX_N = 5e5 + 10;

int n;                   // 巨人数量
int heights[MAX_N];      // 每个巨人的身高
int candies[MAX_N];      // 每个巨人分到的糖果数
ll totalCandies = 0;     // 糖果总数

int main() {
    // 输入巨人数量
    cin >> n;
    
    // 输入每个巨人的身高
    for (int i = 0; i < n; ++i) {
        cin >> heights[i];
    }
    
    // 初始化每个巨人至少分到1个糖果
    for (int i = 0; i < n; ++i) {
        candies[i] = 1;
    }
    
    // 从左到右遍历,确保右边比左边高的巨人分到更多糖果
    for (int i = 1; i < n; ++i) {
        if (heights[i] > heights[i - 1]) {
            if (candies[i] <= candies[i - 1]) {
                candies[i] = candies[i - 1] + 1;
            }
        }
    }
    
    // 从右到左遍历,确保左边比右边高的巨人分到更多糖果
    for (int i = n - 2; i >= 0; --i) {
        if (heights[i] > heights[i + 1]) {
            if (candies[i] <= candies[i + 1]) {
                candies[i] = candies[i + 1] + 1;
            }
        }
    }
    
    // 计算糖果总数
    for (int i = 0; i < n; ++i) {
        totalCandies += candies[i];
    }
    
    // 输出结果
    cout << totalCandies << '\n';
    
    return 0;
}

复杂度分析

  • 时间复杂度:O(n),因为我们只进行了两次线性遍历
  • 空间复杂度:O(n),用于存储身高和糖果数量数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会叫的恐龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值