P5661 [CSP-J2019] 公交换乘

P5661 [CSP-J2019] 公交换乘 解题分析与代码注释

解题思路

这道题目需要模拟公交和地铁的换乘优惠规则,主要考察对队列的应用和优惠券管理的能力。以下是解题的关键点:

  1. 数据结构选择:使用数组模拟队列来存储优惠券信息。虽然STL的queue更简单,但本题需要频繁遍历队列中的元素(检查可用优惠券),而STL queue不支持随机访问,因此手动实现队列更高效。

  2. 优惠券管理:

    • 乘地铁时获得优惠券(入队)

    • 乘公交时查找最早可用的优惠券(遍历队列)

    • 定期清理过期的优惠券(出队)

  3. 时间限制:优惠券有效期为45分钟,需要及时清理过期优惠券以减少不必要的遍历。

  4. 使用规则:公交必须使用可用的最早优惠券,且优惠券金额必须大于等于公交票价。

代码注释

#include<bits/stdc++.h>
using namespace std;

// 定义优惠券结构体
struct node{
    int t,p,f; // t:优惠券获取时间,p:可抵扣金额,f:是否使用过(0未使用,1已使用) 
};

node q[1000010]; // 用数组模拟队列存储优惠券
int head,tail;   // 队列头尾指针,head指向队首,tail指向队尾下一个位置
int n,ans;       // n:乘车记录数量,ans:总花费 

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        int op,p,t; // op:交通类型(0地铁/1公交),p:票价,t:乘车时间
        cin >> op >> p >> t;
        
        if(op == 0) // 地铁乘车记录
        {
            ans += p; // 地铁必须付费,直接加到总花费
            q[tail++] = {t,p,0}; // 获得优惠券,入队(存储时间、票价、未使用状态)
        }
        
        if(op == 1) // 公交乘车记录
        {
            int f = 0; // 标记是否找到可用优惠券,初始为0(未找到)
            
            // 遍历队列查找可用优惠券
            for(int j = head; j < tail; j++){
                // 检查优惠券是否满足条件:
                // 1.在45分钟内(t - q[j].t <= 45)
                // 2.优惠券金额足够(q[j].p >= p)
                // 3.未被使用过(q[j].f == 0)
                if(t - q[j].t <= 45 && q[j].p >= p && q[j].f == 0){
                    q[j].f = 1; // 标记该优惠券为已使用
                    f = 1;      // 标记已找到优惠券
                    break;      // 找到最早可用的就停止
                }
            }
            
            if(f == 0) ans += p; // 没找到可用优惠券,需支付公交费
            
            // 清理过期优惠券(超过45分钟的)
            while(head < tail && t - q[head].t > 45) head++;
        }
    }
    cout << ans; // 输出总花费
    return 0;
}

为什么不使用STL的queue

  1. 遍历需求:题目要求公交乘车时必须查找最早可用的优惠券,这需要遍历队列中的元素。STL的queue不支持随机访问,只能访问队首和队尾。

  2. 高效清理:需要定期清理过期的优惠券,手动实现的队列可以更高效地进行批量出队操作。

  3. 性能考虑:对于大规模数据(n≤10^5),手动实现的数组队列比STL queue有更好的性能表现,减少了容器操作的开销。

  4. 状态修改:需要在遍历过程中修改队列元素的使用状态(f字段),手动实现的队列可以更方便地进行这种操作。

通过手动实现队列,我们可以更灵活地处理优惠券的查找、使用和清理操作,满足题目要求的各项规则

posted @ 2025-05-27 16:04  CRt0729  阅读(129)  评论(0)    收藏  举报