专栏文章

题解:P5661 [CSP-J2019] 公交换乘

P5661题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@miqnz225
此快照首次捕获于
2025/12/04 07:54
3 个月前
此快照最后确认于
2025/12/04 07:54
3 个月前
查看原文

思路

按题意模拟。
用一个双端队列来存优惠票价和获得时间。
如果坐地铁,花费相应的钱数并且往双端队列里面塞一个优惠票。因为输入数据的时间递增,所以双端队列里优惠票的获得时间也是递增。
如果坐公交,先把过期的优惠票从双端队列里面删除,然后判断队首的票价是否能够使用。如果不能够,就把这张票塞到另外一个栈里面存着,并把这张票从双端队列中删除,重复这个过程。如果双端队列空了还没有能用的票,就得原价坐公交车,否则删除能用的票,免费坐公交车。最终还要把存在栈里面的票从队首塞回双端队列里。
因为票的有效期只有 4545 分钟,所以双端队列里面最多只有 4545 张票,时间复杂度为 O(45n)O(45n)

代码

CPP
#include<bits/stdc++.h>
using namespace std;
struct node{
	int t,val;
};
deque<node>q;
stack<node>s;
int n;
int opt,val,t;
int sum;

int main(){
	scanf("%d",&n);
	while(n--){
		scanf("%d%d%d",&opt,&val,&t);
		while(!q.empty()&&t-q.front().t>45)q.pop_front();
		if(opt){
			bool f=0;
			while(!q.empty()){
				if(q.front().val>=val){
					f=1;
					q.pop_front();
					break;
				}
				s.push(q.front());
				q.pop_front();
			}
			while(!s.empty()){
				q.push_front(s.top());
				s.pop();
			}
			if(!f)sum+=val;
		}
		else{
			sum+=val;
			q.push_back({t,val});
		}
	}
	printf("%d",sum);
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...