洛谷 P1315 [NOIP2011 提高组] 观光公交c++(求点赞、关注)

代码

#include <bits/stdc++.h>
using namespace std;
// 乘客结构体,记录乘客的起始点和终点
struct Passenger {
    int start;  // 起始点
    int end;    // 终点
};
// 站点结构体,记录每个站点的信息
struct Station {
    int off;        // 下车乘客数
    int latest;     // 最晚到达时间
    int arrive;     // 实际到达时间
};

int main() {
    int N, M, K;
    cin >> N >> M >> K; // 输入总站点数N,乘客数M,操作次数K
    vector<int> Dist(N); // 景点之间的距离数组
    for (int i = 1; i < N; ++i) {
        cin >> Dist[i]; // 输入每相邻景点之间的距离
    }
    vector<Passenger> passengers(M); // 乘客的行程数组
    vector<Station> stations(N + 1); // 站点信息数组,N+1大小以便于索引1到N
    // 输入每位乘客的起始点、终点,同时更新站点信息
    for (int i = 0; i < M; ++i) {
        int s, t, e;
        cin >> s >> t >> e;
        passengers[i] = {s, e}; // 记录乘客的起始点和终点
        stations[t].latest = max(stations[t].latest, s); // 更新站点t的最晚到达时间
        stations[e].off++; // 终点e有乘客下车
    }
    int time = 0;
    // 计算每个站点的实际到达时间
    for (int i = 1; i <= N; ++i) {
        stations[i].arrive = time; // 站点i的实际到达时间为当前时间
        time = max(time, stations[i].latest); // 更新当前时间为当前时间和站点i的最晚到达时间的最大值
        time += Dist[i]; // 加上从当前站点到下一个站点的距离
    }
    // 进行K次操作
    while (K--) {
        int max_num = 0;
        int max_pos = 0;
        // 找出最佳操作位置max_pos
        for (int i = 2; i <= N; ++i) {
            if (Dist[i-1] == 0) continue; // 如果相邻景点距离为0,跳过
            int tmp_num = 0;
            // 计算从位置i开始直到末尾的乘客下车数量之和
            for (int j = i; j <= N; ++j) {
                tmp_num += stations[j].off;
                if (stations[j].arrive <= stations[j].latest) break; // 如果实际到达时间早于等于最晚到达时间,停止计数
            }
            // 找出乘客下车数量最多的位置max_pos
            if (tmp_num > max_num) {
                max_num = tmp_num;
                max_pos = i;
            }
        }
        // 在max_pos处进行一次操作,减少Dist[max_pos-1]的距离
        Dist[max_pos - 1]--;
        // 更新从max_pos开始的站点的实际到达时间
        for (int i = max_pos; i <= N; ++i) {
            stations[i].arrive--; // 实际到达时间减一
            if (stations[i].arrive < stations[i].latest) break; // 如果实际到达时间早于最晚到达时间,停止更新
        }
    }
    int ans = 0;
    // 计算所有乘客的等待时间总和
    for (int i = 0; i < M; ++i) {
        ans += stations[passengers[i].end].arrive - passengers[i].start; // 终点实际到达时间减去起始点,累加到结果中
    }
    cout << ans << endl; // 输出最终答案
    return 0;
}

这段代码实现了一个模拟乘客乘车等待时间的算法,以下是代码的主要思路总结:

  1. 输入处理

    • 首先从输入中读取总站点数 N、乘客数 M 和操作次数 K
    • 读取每相邻景点之间的距离,并存储在 Dist 数组中。
  2. 数据结构定义

    • Passenger 结构体记录了每位乘客的起始点和终点。
    • Station 结构体用来记录每个站点的信息,包括乘客下车数 off、最晚到达时间 latest 和实际到达时间 arrive
  3. 乘客信息录入

    • 循环读取每位乘客的起始点、终点和预计到达时间,并更新 passengers 数组。
    • 同时更新 stations 数组中的 latest 和 off 字段,用于后续计算。
  4. 计算实际到达时间

    • 初始化 time 为 0,依次计算每个站点的实际到达时间:
      • stations[i].arrive 记录为当前时间 time
      • 更新 time 为当前时间与该站点最晚到达时间 stations[i].latest 的较大值。
      • 加上从当前站点到下一个站点的距离 Dist[i],更新 time
  5. 操作模拟

    • 执行 K 次操作,每次操作选择使乘客等待时间总和最小化的站点。
    • 遍历站点,找到使得乘客下车数量最多的位置 max_pos
    • 在 Dist[max_pos - 1] 上减少距离,并更新从 max_pos 开始的站点的实际到达时间。
  6. 计算结果

    • 最后计算所有乘客的等待时间总和 ans
    • 通过累加每位乘客的实际到达时间与起始点时间的差值,得到最终结果。
  7. 输出

    • 输出最终计算得到的等待时间总和 ans

该算法通过模拟实际乘客行程和每次操作后的影响,动态调整各站点的到达时间,以求得最小化乘客等待时间总和。

链接:[NOIP2011 提高组] 观光公交 - 洛谷

求点赞、关注 

  • 20
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值