题解:学而思编程 跑车与旅行

【题目来源】

学而思编程:跑车与旅行

【题目描述】

小猴终于打算驾驶自己心爱的小跑车去旅行了,为此他已经规划好了一个旅游线路,要依次参观 \(n\) 个城市(包括自己的城市)。小猴有加油强迫症,即每到一个城市,一定会将自己跑车的油箱彻底加满,否则就会浑身难受。

已知小猴的跑车每跑一公里都会消耗一升汽油,现在依次告诉你每个城市中每升汽油的价格,以及该城市与上一个到达城市的距离(单位为公里,起点城市距离自己为 \(0\))。请你帮助小猴计算到达终点城市的总加油花费(当然到最后一个城市也需要加油),但是如果小猴到不了最后的城市,请提前告诉他。

【输入】

第一行两个正整数 \(n,c\),分别表示城市的数量与小猴跑车的油箱容量。

第二行 \(n\) 个整数,表示该城市与上一个城市的距离 \(d_i\)

第三行 \(n\) 个整数,表示该城市每升汽油的价格 \(p_i\)

【输出】

如果小猴能够到达,请输出购买汽油总花费,否则输出他最后一个到达城市的编号。

【输入样例】

3 3
0 2 3
3 2 1

【输出样例】

16

【核心思想】

  1. 问题分析:小猴依次参观 \(n\) 个城市,每到一个城市必须加满油(容量 \(c\))。已知每段距离 \(d_i\) 和每升油价 \(p_i\),求到达终点的总花费;若无法到达则输出最后到达的城市编号。这是一个贪心策略 + 可行性判断问题,关键在于理解"每到一个城市加满油"意味着每段路程的油耗由当前城市的油价决定。

  2. 算法选择

    • 贪心累加:每段路程 \(d_i\) 的油耗在当前城市购买,花费为 \(d_i \times p_i\)
    • 可行性检查:若某段距离 \(d_i > c\)(超过油箱容量),则无法到达,返回上一个城市编号
  3. 关键步骤

    • 初始化:读取 \(n\)(城市数)和 \(c\)(油箱容量)
    • 读取数据
      • 读取距离数组 \(d[1..n]\)\(d_1 = 0\) 为起点)
      • 读取油价数组 \(p[1..n]\)
    • 计算总花费
      • sum = c * p[1]:在第一个城市加满油的花费
      • 遍历 \(i\)\(2\)\(n\)
        • d[i] > c:无法到达第 \(i\) 个城市,返回 i - 1(最后到达的城市编号)
        • 否则:sum += d[i] * p[i]:在第 \(i\) 个城市购买行驶 \(d_i\) 公里所需的油
    • 输出 sum(能到达终点时)或 i - 1(无法到达时)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n)\),线性遍历城市
    • 空间复杂度:\(O(n)\),存储距离和油价数组
  5. 贪心累加的核心思想

    • 强制满油策略:每到一个城市必须加满油,意味着油箱在离开每个城市时都是满的 \(c\) 升,但实际花费只与行驶该段路程所需的油量有关
    • 路段独立性:每段路程 \(d_i\) 的油耗必须在城市 \(i\) 购买(因为离开时必须满油,而到达时油箱剩余 \(c - d_i\),需加 \(d_i\) 升才能满),因此花费为 \(d_i \times p_i\)
    • 可行性判定:单段距离超过油箱容量 \(c\) 时,无论如何都无法通过,提前终止
    • 起点特殊处理:起点距离为 \(0\),但题目要求"到最后一个城市也需要加油",因此初始花费为 \(c \times p_1\)(在起点加满)
    • 适用于"强制状态转移 + 路段费用累加"类问题,贪心策略将复杂规划简化为线性扫描

【算法标签】

模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int n, c, d[100005], p[100005];

// 计算最小消耗
long long cal()
{
    long long sum = c * p[1];  // 初始化总和为第一个位置的成本
    for (int i = 2; i <= n; i++)
    {
        // 如果当前位置距离大于c,则无法到达
        if (d[i] > c)
        {
            return i - 1;  // 返回上一个位置
        }
        else
        {
            sum += d[i] * p[i];  // 累加消耗
        }
    }
    return sum;  // 返回总消耗
}

int main()
{
    cin >> n >> c;
    for (int i = 1; i <= n; i++)
    {
        cin >> d[i];  // 读取距离
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> p[i];  // 读取单位消耗
    }
    cout << cal() << endl;
    return 0;
}

【运行结果】

3 3
0 2 3
3 2 1
16
posted @ 2026-07-04 15:09  团爸讲算法  阅读(3)  评论(0)    收藏  举报