公交换乘C++

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

题目:


 

 

 


样例解释:

样例#1:
第一条记录,在第 3 分钟花费 10 元乘坐地铁。
第二条记录,在第 46 分钟乘坐公交车,可以使用第一条记录中乘坐地铁获得的优惠票,因此没有花费。
第三条记录,在第 50 分种花费 12 元乘坐地铁。
第四条记录,在第 96 分钟乘坐公交车,由于距离第三条记录中乘坐地铁已超过 45 分钟,所以优惠票已失效,花费 3 元乘坐公交车。
第五条记录,在第 110 分钟花费 5 元乘坐地铁。
第六条记录,在第 135 分钟乘坐公交车,由于此时手中只有第五条记录中乘坐地铁获得的优惠票有效,而本次公交车的票价为 6 元,高于第五条记录中地铁的票价 5 元,所以不能使用优惠票,花费 6 元乘坐公交车。
总共花费 36 元。
样例#2:
第一条记录,在第 1 分钟花费 5 元乘坐地铁。
第二条记录,在第 16 分钟花费 20 元乘坐地铁。
第三条记录,在第 23 分钟花费 7 元乘坐地铁。
第四条记录,在第 31 分钟乘坐公交车,此时只有第二条记录中乘坐的地铁票价高于本次公交车票价,所以使用第二条记录中乘坐地铁获得的优惠票。
第五条记录,在第 38 分钟乘坐公交车,此时第一条和第三条记录中乘坐地铁获得的优惠票都可以使用,使用获得最早的优惠票,即第一条记录中乘坐地铁获得的优惠票。
第六条记录,在第 68 分钟乘坐公交车,使用第三条记录中乘坐地铁获得的优惠票。
总共花费 32 元。
样例#3:
第一条记录,在第 1 分钟花费 5 元乘坐地铁。
第二条记录,在第 16 分钟花费 6 元乘坐地铁。
第三条记录,在第 23 分钟花费 10 元乘坐地铁。
第四条记录,在第 47 分钟乘坐公交车。此时由于距离第一条记录中乘坐地铁已超过 45 分钟,所以优惠票已失效;第二,三条记录中的优惠票有效,但本次公交票价为 7 元,高于第二条的优惠票,只有第三条记录中的优惠票可以使用,所以使用第三条记录的优惠票。
第五条记录,在第 50 分钟乘坐公交车,此时第二,三条记录的优惠票有效,但第三条记录的优惠票已经使用,第二条记录的优惠票高于本次公交票价,所以使用第二条记录的优惠票。
第六条记录,在第 55 分钟乘坐公交车,第一条记录的优惠票已失效,第二,三条记录的优惠票已使用,花费 10 元乘坐公交车。
总共花费 31 元。


 思路:

用一个数组来装所有的收集到的赠票。每当坐地铁的时候,就直接花钱,然后获得一张赠票,放到数组里面。每当坐公交的时候,看看数组里面有没有时间合适,价格小于现在公交票价的赠票,并且没用过的赠票,直接用时间最早的那一张就可以了。

每张赠票要存三个信息,因此用一个结构体来存。数据不超过105105,因此开一个105105长度的数组。

const int MAXN = 100005;
struct Ticket {
    //赠票的价格,最晚使用时间和是否需用过
    int price, time, used;
} q[MAXN];//赠票盒子

然而,出题人会这么善良么?NO,NO,NO,显然不会。我们想想极限情况什么样子,极限数据105105,假设开始的时候全坐地铁,坐了5∗1045∗104 次以后,我们的盒子里面有好多票啊。后面全坐公交,要坐5∗1045∗104 次,每次都在这个大盒子里面找合适的票,复杂度O(n2)O(n2),总计算量2.5∗1092.5∗109,我们在超时的边缘疯狂试探啊。

怎么优化呢?关键点在于题中说每次坐车开始时间都不重合,而且45分钟票就过期。所以理论上来讲,盒子里最多也就有45张没过期的票。大量的票都是已经过期了的,没必要从头扫一遍数组,在大量过期的票中浪费宝贵的青春。所以我们想到类似手写队列的方法,定义一个head变量和一个tail变量,分别表示目前还没过期的第一张票的位置,和下一张新的赠票在数组里要插入的位置,每次从head到小于tail循环即可。每次最多循环45次,总共105105次循环,肯定不会超时。

 其余细节看代码注释吧。不要复制粘贴哦,理解题目才是王道!!!


 

#include <iostream>
using namespace std;
const int MAXN = 100005;
struct Ticket {
    //赠票的价格,最晚使用时间和是否需用过
    int price, time, used;
} q[MAXN];//赠票盒子
int head, tail, n, cost;

int main() {
    cin >> n;
    for (int i = 0; i < n; ++i) {
        int op, price, time;
        //输入每次坐车的种类,价格和发车时间
        cin >> op >> price >> time;
        if (op == 0) {
            //如果是坐地铁,直接把价格加到cost里面
            cost += price;
            //新一张赠票插入数组末尾,这张票的最晚使用时间是当前时间+45
            q[tail].time = time + 45;
            //赠票面额就是地铁票价
            q[tail++].price = price;
        } else {
            //先用一个循环把过期票扔掉
            while (head < tail && q[head].time < time) {
                head++;
            }
            bool found = false;//表示是否有合适的赠票,先假设没有
            for (int j = head; j < tail; ++j) {
                //循环所有剩余的票,这些一定都没过期,因为题目中时间是按顺序给我们的
                if (q[j].price >= price && q[j].used == 0) {
                    //如果价格合适,并且没用过,标记找到了,这张票标记用过
                    found = true;
                    q[j].used = 1;
                    break;
                }
            }
            //如果没找到合适的赠票,老老实实花钱买吧
            if (!found) cost += price;
        }
    }
    cout << cost << endl;
    return 0;
}

C++公交换乘(队列练习) 第六条记录,在第 135 分钟乘坐公交车,由于此时手中只有第五条记录中乘坐地铁获得的优惠票有效,而本次公交车的票价为 6 元,高于第五条记录中地铁的票价 5 元,所以不能使用优惠票,花费 6 元乘坐公交车。第五条记录,在第 38 分钟乘坐公交车,此时第一条和第三条记录中乘坐地铁获得的优惠票都可以使用,使用获得最早的优惠票,即第一条记录中乘坐地铁获得的优惠票。第四条记录,在第 31 分钟乘坐公交车,此时只有第二条记录中乘坐的地铁票价高于本次公交车票价,所以使用第二条记录中乘坐地铁获得的优惠票。 阅读详情

相关推荐

DOTCPP1282: 公交汽车,c++代码实现

题目 1282: 公交汽车 网站:DOTCPP

Lomid1024的博客 516

C++公交换乘系统.docx

C++公交换乘系统.docxC++公交换乘系统.docxC++公交换乘系统.docxC++公交换乘系统.docxC++公交换乘系统.docxC++公交换乘系统.docxC++公交换乘系统.docxC++公交换乘系统.docx

C++洛谷P5661,[CSP-J2019]公交换乘题解+de小bug

C++洛谷P5661,[CSP-J2019]公交换乘题解+de小bug C 思路 算法:队列,模拟。 重点:读入每一张有效优惠券的终止时间,价格。 模拟每一条公交车记录是否可以用票抵消。 如果可以,用最早的有效优惠票。 否则,用钱买车票。 Code: #include<iostream> #include<cstdio> using namespace std; struct piao { int p; int t; }; piao a[100005]; int n; i

Jacggs的博客 2012

公交换乘系统 C++实现

由于换乘麻烦,自己做了一个小的换乘系统,

公交换乘怎么做c++

公交换乘怎么做c++求助大佬

ITlearing的博客 1798

C++知识点总结(23):高级模拟算法

现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。总花费中,地铁是必须花费的,公交车可能不花钱(坐地铁后有赠票),但是与时间和价格有一定关系。行,一个整数,表示所求的地毯的编号;的破译过程是这样的:扫描原信息,对于原信息中的字母。的地毯的信息,包含四个整数。,表示所求的地面的点的坐标(

joe_g12345的博客 1154

北京上海公交地铁换乘规划工具(Qt/C++实现,支持Dijkstra与A*算法)

一款基于Qt和C++开发的本地化桌面应用,专为北京、上海两地设计,能快速查询公交与地铁线路并智能规划换乘路径。支持多种优化目标:最少换乘次数、最短总耗时、最少步行距离等,底层集成Dijkstra与A*两种经典路径搜索算法,兼顾精度与效率。界面采用QGraphicsView自定义缩放组件,可流畅拖拽、缩放查看完整线路图;内置站点数据管理模块(Station类)、线路图渲染引擎(VehicleMap类),以及预处理好的地图资源(如map.png、metro-shanghai.png、station.png等)。

ss78901的博客 222

[Luogu]P5661 公交换乘(C++题解)

洛谷练习题 P5661 公交换乘(普及+/提高-难度)C++题解

CSDN14261716的博客 1077

P5661 [CSP-J2019] 公交换乘

今天zty带来的是 P5661 [CSP-J2019] 公交换乘 时,大家给个赞呗,zty还要上学,发作品会少一点先 赞 后 看 养 成 习 惯先 赞 后 看 养 成 习 惯。

zty20120913的博客 753

C++实用技巧:公交换乘算法

需求          功能演示截图      路线稍微有小点修改 有偿技术支持与服务以及源代码获取        请加QQ:21497936

长沙红胖子 Qt・西安|省级科研团队从业背景,深耕双一流体系高精尖技术配套研发|剥离高精尖机理,沉淀高端特种行业领域 Qt 工程化落地经验|博文仅分享通用技术总结,输出公开普适工程思路。 4万+

公交换乘查询系统

公交换乘查询系统

luogu P5661 公交换乘

题面传送门 这道题是一道简单的模拟…(xyh:what?)(xyh:what?)(xyh:what?)首先我们要感谢可爱的c++c++c++的STLSTLSTL库,使得我们可以不用写循环队列。尽管这道题根本不用循环队列。我们开一个fff数组来表示这个队列,其中这是个双端队列。当我们碰到一张transfertransfertransfer票时,我们就把他加入这个队列中,当我们刚好遇见一张busbus...

fxt275307894a的博客 365

CSP-J2019真题——公交换乘

CSP-J2019真题——公交换乘

PanDaoxi 1825

[CSP-J 2019] 公交换乘

这一题做好久啦,一个多小时了!喜欢的同学点点收藏和关注吧,就算是一个小小的赞我也会很开心啊QAQ

sxj_c的博客 1026

基于双向 BFS 的公交换乘最优路径规划系统设计与实现

本文设计的基于双向 BFS 的公交换乘路径规划系统,通过 “以线路为搜索节点” 的创新设计,高效实现了最少换乘次数的路径规划。系统具备完善的异常处理机制,能够友好响应用户输入,在日常出行、智能导航等场景中具有较高的实用价值。

2503_93754117的博客 794

洛谷普及组[CSP-J2019] 公交换乘

洛谷公交换乘

qq_41250497的博客 444

NOIP公交换乘

这道题是noip复赛题,我今天跟大家讲一讲。 首先,上题目。 题目描述 著名旅游城市 B 市为了鼓励大家采用公共交通方式出行,推出了一种地铁换乘公交车的优惠方案: 1.在搭乘一次地铁后可以获得一张优惠票,有效期为 45 分钟,在有效期内可以消耗这张优惠票,免费搭乘一次票价不超过地铁票价的公交车。在有效期内指开始乘公交车的时间与开始乘地铁的时间之差小于等于 45 分钟,即: tbus- tsubway≤45 2.搭乘地铁获得的优惠票可以累积,即可以连续搭乘若干次地铁后再连续使用优惠票搭乘公交车。 .

dingzhekai的博客 806

南沙C++信奥赛陈老师解一本通题 1983:【19CSPJ普及组】公交换乘

第六条记录,在第 135 分钟乘坐公交车,由于此时手中只有第五条记录中乘坐地铁获得的优惠票有效,而本次公交车的票价为 6 元,高于第五条记录中地铁的票价 5 元,所以不能使用优惠票,花费 6 元乘坐公交车。第五条记录,在第 38 分钟乘坐公交车,此时第一条和第三条记录中乘坐地铁获得的优惠票都可以使用,使用获得最早的优惠票,即第一条记录中乘坐地铁获得的优惠票。第四条记录,在第 31 分钟乘坐公交车,此时只有第二条记录中乘坐的地铁票价高于本次公交车票价,所以使用第二条记录中乘坐地铁获得的优惠票。

vx_cyf1333888的博客 686

NOIP普及组 - 2019 - 公交换乘 题解

先来一个传送门 本题在洛谷难度定为“普及-”,其实并不是很难,但我第一次做的时候只有30分,剩余的都是TLE, 在我进行了一个修改后就AC了。 本题我用的是一个结构体和一个main函数,先来看看结构体 struct Node{ long long time, price, vis = 0; // 没被用过是1,用过是2 }a[100010]; 每次乘地铁时进行一个这样的操作, 如果没看出有什么用,那就看接下来的代码 int main(){ long long n, x, y, z, sum = 0,

williamllk的博客 1413
上一篇: 数字游戏C++
下一篇: 加工零件C++
猫武士水星
博客等级 码龄3年 714粉丝 125原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值