「CSP-J2019」交通换乘 题解
转自博客。
一道橙题
,但是会T。
题面
[CSP-J2019] 公交换乘
题目描述
著名旅游城市 B 市为了鼓励大家采用公共交通方式出行,推出了一种地铁换乘公交车的优惠方案:
- 在搭乘一次地铁后可以获得一张优惠票,有效期为 45 分钟,在有效期内可以消耗这张优惠票,免费搭乘一次票价不超过地铁票价的公交车。在有效期内指开始乘公交车的时间与开始乘地铁的时间之差小于等于 45 分钟,即:
- 搭乘地铁获得的优惠票可以累积,即可以连续搭乘若干次地铁后再连续使用优惠票搭乘公交车。
- 搭乘公交车时,如果可以使用优惠票一定会使用优惠票;如果有多张优惠票满足条件,则优先消耗获得最早的优惠票。
现在你得到了小轩最近的公共交通出行记录,你能帮他算算他的花费吗?
输入格式
输入文件的第一行包含一个正整数
接下来的
我们保证出行记录是按照开始乘车的时间顺序给出的,且不会有两次乘车记录出现在同一分钟。
输出格式
输出文件有一行,包含一个正整数,代表小轩出行的总花费。
样例 #1
样例输入 #1
6
0 10 3
1 5 46
0 12 50
1 3 96
0 5 110
1 6 135
样例输出 #1
36
样例 #2
样例输入 #2
6
0 5 1
0 20 16
0 7 23
1 18 31
1 4 38
1 7 68
样例输出 #2
32
提示
【输入输出样例 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 元。
【数据规模与约定】
对于
另有
另有
对于
PS:其实你可以点这个复制而不用慢慢改格式qaq
解析
很明显,这道题只需要使用一个结构体数组来模拟门票,如果时间在ticket.can
(票可以用)这三个条件即可,因为要求优先消耗获得最早的优惠票,所以从最前面开始查找就行了。
于是,你很轻易地写出了这个代码:
#include <bits/stdc++.h>
using namespace std;
struct ticket{
int time;
int price;
bool can=1;
};
inline void read(int &n){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar(); //PS:不用快读可能炸
}
n=x*f;
}
int main(){
// freopen("P5661_9.in","r",stdin);
// freopen("P5661_9.ans","w",stdout);
int n,s=0,l=1;
ticket t[114514];
read(n);
for(int i=1;i<=n;i++){
int b,tim,p;
read(b);read(p);read(tim);
if(b==0){
t[l].time=tim;
t[l].price=p;
l++;
s+=p;
}
if(b==1){
int flag=1;
for(int j=1;j<l;j++){
if(t[j].can&&t[j].price>=p&&tim-t[j].time<=45){
t[j].can=0;
flag=0;
break;
}
}
if(flag){
s+=p;
}
}
}
cout<<s;
return 0;
}
恭喜你喜提
我们想想,所有的数据,
怎么优化呢?我们想想,是不是每一次坐公交车的时候找票都只找没过期的票,是吧。因为时间是升序排列的,所以我们每一次找票的时候根本不需要在前面的一堆烂票里面浪费自己的美好年华。我们不如用一个变量
代码
#include <bits/stdc++.h>
using namespace std;
struct ticket{
int time; //时间
int price; //价值
bool can=1; //能不能用
}t[114514]; //结构体数组
inline void read(int &n){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
} //PS:不用快读,甚至cin也能过,但40+ms的读入浪费,显然不太好
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
n=x*f;
}
int main(){
// freopen("P5661_9.in","r",stdin);
// freopen("P5661_9.ans","w",stdout);
int n,s=0,l=1,x=1;
read(n);
for(int i=1;i<=n;i++){
int b,tim,p;
read(b);read(p);read(tim);
if(b==0){ //地铁,并且往数组里面扔一个票
t[l].time=tim;
t[l].price=p;
l++;
s+=p;
}
if(b==1){ //公交
int flag=1; //用票与否
for(int j=x;j<l;j++){
if(t[j].can&&t[j].price>=p&&tim-t[j].time<=45){ //满足三个条件就能用
t[j].can=0;
flag=0; //用票
break; //找到能用的票就退出
}
if(tim-t[j].time>45){
x=j; //超时了前面的就不要了
}
}
if(flag){
s+=p; //不用票
}
}
}
cout<<s;
return 0;
}
本文作者:Ariasaka
本文链接:https://www.cnblogs.com/LYXOfficial/p/17648731.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步