首页 > 其他分享 >【题解】[CSP-J 2019] 公交换乘

【题解】[CSP-J 2019] 公交换乘

时间:2024-06-09 09:54:40浏览次数:14  
标签:head 记录 int 题解 优惠 票价 tail 2019 CSP

题目描述

题目大意

给出 \(n\) 次出行记录(地铁 或 公交车),有以下优惠方案:

  1. 搭乘一次地铁后可以获得一张有效期为45分钟的优惠票,可以免费搭乘一次票价不超过该地铁票价的公交车。
  2. 优惠票可以累计存储
  3. 优先使用过期时间早的优惠票。

思路

枚举每一次出行:

  • 如果是地铁。累加花费,并记录优惠票。
  • 如果是公交车。寻找优惠票抵消,特别的如果没有优惠票可以使用,需要累加花费。

代码

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

const int N = 1e5 + 5;
int n;

struct ticket // 定义结构体储存优惠票 
{
    int p; // 票价
    int t; // 过期时间
    bool vis; // 是否使用过 
};
ticket q[N]; // 用队列记录优惠票
int head, tail;

int main()
{
    scanf("%d", &n);

    int ans = 0; // 记录总花费
    while(n -- )
    {
        int opt, p, t; scanf("%d%d%d", &opt, &p, &t); // 分别输入 交通工具、票价、时间
        if (opt == 0) // 如果乘坐地铁
        {
            ans += p; // 将票价加到总花费上

            q[tail ++ ] = {p, t + 45, false}; // 记录优惠票(票价为 p,结束时间为 t+45,未使用)
        }
        else // 如果乘坐公交车
        {
            while (head < tail && q[head].t < t) // 剔除过期的优惠票
                head ++ ;

            bool f = false; // 记录是否使用了优惠票
            // 因为题目是按时间顺序给出的,所以第一张可以使用的优惠票,必定是最早的优惠票
            for (int i = head; i < tail; i ++ )
                if (q[i].vis == false && q[i].p >= p) // 如果找到了合适的优惠票
                {
                    q[i].vis = true; // 记录该优惠票已使用
                    f = true; // 记录使用了优惠票
                    break;
                }
            if (!f) // 如果没有找到合适的优惠票,就只能付钱
                ans += p; // 将票价加到总花费上
        }
    }
    printf("%d\n", ans); // 输出总花费

    return 0;
}

标签:head,记录,int,题解,优惠,票价,tail,2019,CSP
From: https://www.cnblogs.com/T-hong/p/18239276

相关文章

  • [题解]P6374 「StOI-1」树上询问
    题意简述给定一个\(N\)个节点的树,接下来有\(q\)次询问。每次询问给定\(a,b,c\),请问存在多少个节点\(i\),使得这棵树在以\(i\)为根的情况下,\(a\)和\(b\)的LCA是\(c\)。解题思路首先通过分析样例,我们发现:\(a,b\)的LCA一定在它们之间的简单路径上,所以如果\(c\)不在\(a,b\)之间的简......
  • CF1552G A Serious Referee 题解
    题目链接点击打开链接题目解法感觉很神奇的题首先把序列当成排列做首先发现只要当成\(01\)序列做就是对的为什么?你假设有数\(x<y\),你把\(\lex\)的数设成\(0\),\(>x\)且\(\ley\)的数设成\(1\),\(>y\)的数设成\(2\),然后做题目中的排序操作,如果最终序列形成逆序......
  • CF717G Underfail 题解
    题意:若干区间,区间有权值,选择一个子集,使得权值和尽量大并且每个点不被覆盖超过\(x\)次。\(n\le500\)思路:很神奇的一道题。我们考虑费用流,如果单纯的一边是区间一边是点的话其实并不好做,所以这道题我们直接建一排\(n+2\)个点,一个区间\(l,r\)就从\(l\)到\(r+1\)连......
  • CCF-GESP 等级考试 2023年9月认证C++四级真题解析
    一、单选题(每题2分,共30分)第1题⼈们所使⽤的⼿机上安装的App通常指的是()。A.⼀款操作系统B.⼀款应⽤软件C.⼀种通话设备D.以上都不对正确答案:B.⼀款应⽤软件解析:App是"Application"的缩写,中文意思是"应用",特指安装在智能手机上的第三方应用软件。这些软件通常......
  • 打砖块 题解
    题目链接\(50pts\)对于没有\(Y\)砖的情况,可以用分组背包解决,算出每一列打\(j\)块砖需要的子弹以及对分数的贡献,按照分组背包即可。对于包含\(Y\)砖的情况,不能直接分组背包解决。这实际上是打的顺序问题,比如:NYNY如果手上有两枚子弹,最优策略是先打掉第二列,再打掉第......
  • 【Selenium+java环境配置】(超详细教程常见问题解决)
    Selenium+java环境配置windows电脑环境搭建-chrome浏览器1.下载chrome浏览器2.查看chrome浏览器版本3.下载chrome浏览器驱动4.配置系统环境变量PATH验证环境是否搭建成功1.创建java项目,添加pom文件中添加依赖2.编写代码运行常见问题&解决办法1.访问失败Theversio......
  • 猜排列 题解
    猜排列题解差eps步想到正解。题意描述有\(m\)个长为\(n\)序列\(a_1,\dots,a_n\),还有\(m\)个长为\(n\)序列\(b_1,\dots,b_n\)。其中\(b_i\)是由\(a_i\)通过排列\(p\)置换得到的,\(b_{p_i}=a_i\)。现在又要求出排列\(p\)会有多种可能,模\(998244353\)。So......
  • P10466 邻值查找 题解
    题目传送门前置知识二叉搜索树&平衡树解法笔者写这篇题解的时候题面应该是出锅了,建议去看Acwing的题面。第一问同luoguP2234[HNOI2002]营业额统计,平衡树维护前驱、后继(非严格意义上的)求出差值后取\(\min\)即可;第二问用map实现一个映射即可维护位置。代码#incl......
  • P10499 开关问题 题解
    题目传送门前置知识高斯消元法解异或方程组|乘法原理解法把开关的相互影响关系转化成异或,然后就转化成了异或方程组,高斯消元求解即可。判断是否存在解的过程同luoguP2455[SDOI2006]线性方程组。由于自由元仅能取\(0/1\),故总方案数为\(2\)的自由元数量次方。代码......
  • P7219 [JOISC2020] 星座 3 题解
    会发现题目的坐标其实是平面直角坐标系。我们按\(y\)坐标从小到大考虑所有的星星,假设当前考虑到了星星\(i\)。我们先计算出之前所有能够影响到\(i\)的星星的代价和为\(cost\)(可以用树状数组维护)。然后分类讨论。若\(c_i\lecost\),那么肯定直接将\(i\)直接涂黑,因为它更......