题目基本信息
原题链接https://www.luogu.com.cn/problem/P5661
样例
输入: 输出:
6 36
0 10 3
1 5 46
0 12 50
1 3 96
0 5 110
1 6 135
题意分析
简化题意
乘坐地铁将获得与花费等额的优惠券,有效期45分钟。乘坐公交时,可以使用价格≥公交花费的优惠券,无需付钱。当有多个可以使用的优惠券时,优先使用最早获得的优惠券。
解题思路
看到题目后的第一想法是用数据结构存储优惠券,然后根据题意模拟即可。
如果乘坐地铁,总花费直接加上当前花费,存入优惠券和时间。
如果乘坐公交,判断有没有可用的优惠券,有就使用,没有就交钱。在这个过程中,顺便把过期的优惠券扔掉(确信)。
鉴于先进先出的结构,以及每一个优惠券需要存储两个变量的特点,使用队列+结构体存储。
代码细节
- 获得优惠券的时间要用long long存储
- 为了使优惠券之间的顺序不变,每次遍历队列判断是否过期时都需要遍历完整队列,并使用负责中转的队列q2辅助存储。具体可以看代码
代码实现
定义
const int N=100010;
typedef long long ll;
struct node{
ll t;
int price;
};
queue<node>q1,q2;
ll res;
int n,mk[N];
int op,ti,pri;
bool flag;
乘坐地铁的情况
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d",&op,&pri,&ti);
if(op==0)
{
res+=pri;
q1.push((node){ti,pri});
乘坐公交的情况
}else{
while(q1.size())
{
node tmp=q1.front();
if((ti-tmp.t)>45) q1.pop();
else break;
}
flag=false;
while(q1.size())//双队列,q2是一个中转
{
node tmp=q1.front();
q1.pop();
if(tmp.price>=pri && !flag)
{
flag=true;
continue;
}
q2.push(tmp);
}
if(!flag) res+=pri;
while(q2.size())//存回q1
{
node tmp=q2.front();
q2.pop();
q1.push(tmp);
}
}
}
printf("%lld",res);
return 0;
}
完整代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<stack>
#include<queue>
using namespace std;
const int N=100010;
typedef long long ll;
struct node{
ll t;
int price;
};
queue<node>q1,q2;
ll res;
int n,mk[N];
int op,ti,pri;
bool flag;
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d",&op,&pri,&ti);
if(op==0)
{
res+=pri;
q1.push((node){ti,pri});
}else{
while(q1.size())
{
node tmp=q1.front();
if((ti-tmp.t)>45) q1.pop();
else break;
}
flag=false;
while(q1.size())//双队列,q2是一个中转
{
node tmp=q1.front();
q1.pop();
if(tmp.price>=pri && !flag)
{
flag=true;
continue;
}
q2.push(tmp);
}
if(!flag) res+=pri;
while(q2.size())
{
node tmp=q2.front();
q2.pop();
q1.push(tmp);
}
}
}
printf("%lld",res);
return 0;
}
好久没写题解了,写的有点菜,希望各位大神批评指正