PAT甲级——1033 To Fill or Not to Fill——分数 25

题目

题目大意是,计算最便宜的油费,起点的油必须加,后面的油选便宜的加


解法1

点击查看代码
#include <iostream> // 输入输出
#include <vector>   // 使用 vector
#include <algorithm> // 使用 sort 排序
#include <iomanip>   // 设置输出精度
using namespace std;

// 加油站结构体,包含油价和距离
struct Station {
    double price;     // 每升油的价格
    double distance;  // 距离起点的距离
};

// 按照距离升序排列加油站
bool cmp(Station a, Station b) {
    return a.distance < b.distance;
}

int main() {
    double Cmax, D, Davg; // 油箱容量,总距离,每升油能跑的距离
    int N;                // 加油站数量
    cin >> Cmax >> D >> Davg >> N; // 读入基本信息

    vector<Station> stations(N); // 存储加油站
    for (int i = 0; i < N; ++i) {
        cin >> stations[i].price >> stations[i].distance; // 读入加油站信息
    }

    stations.push_back({0, D}); // 添加一个终点作为虚拟加油站,价格为0
    sort(stations.begin(), stations.end(), cmp); // 按照距离升序排序

    if (stations[0].distance != 0) { // 如果起点没有加油站,不能出发
        cout << "The maximum travel distance = 0.00" << endl;
        return 0;
    }

    double maxDistance = Cmax * Davg; // 一箱油最多能跑的距离
    double totalCost = 0;             // 总花费
    double currentTank = 0;           // 当前油量
    double currentPos = 0;            // 当前距离
    int currentIndex = 0;             // 当前所在加油站索引

    while (currentPos < D) { // 只要还没到终点
        int nextIndex = -1;       // 记录下一个加油站索引
        double minPrice = 1e9;    // 初始化最小价格为极大值

        // 寻找在当前油量能到达范围内的加油站
        for (int i = currentIndex + 1; i < stations.size(); ++i) {
            double gap = stations[i].distance - currentPos; // 距离下个加油站有多远
            if (gap > maxDistance) break; // 超出一桶油的最大行驶距离,退出循环

            if (stations[i].price < minPrice) { // 找到更便宜的
                minPrice = stations[i].price;
                nextIndex = i;
                if (stations[i].price < stations[currentIndex].price) break; // 优于当前价格则直接选
            }
        }

        if (nextIndex == -1) { // 找不到能到的加油站
            printf("The maximum travel distance = %.2f\n", currentPos + maxDistance);
            return 0;
        }

        double needed = (stations[nextIndex].distance - currentPos) / Davg; // 到下一个站需要的油量

        if (stations[nextIndex].price < stations[currentIndex].price) {
            // 下一个站更便宜,买刚好够用的油
            if (currentTank < needed) {
                totalCost += (needed - currentTank) * stations[currentIndex].price; // 花钱加油
                currentTank = 0; // 到了就没油了
            } else {
                currentTank -= needed; // 现有油够用,直接消耗
            }
        } else {
            // 没有更便宜的,加满油
            totalCost += (Cmax - currentTank) * stations[currentIndex].price; // 加满油
            currentTank = Cmax - needed; // 到下一站还剩的油
        }

        currentPos = stations[nextIndex].distance; // 更新当前位置
        currentIndex = nextIndex;                 // 更新加油站索引
    }

    printf("%.2f\n", totalCost); // 输出总花费,保留2位小数
    return 0;
}

posted on 2025-05-13 08:32  LEESOL-cn  阅读(11)  评论(0)    收藏  举报

导航