PAT (Advanced Level) Practice: 1095 Cars on Campus (30 分)

1095 Cars on Campus (30 分)

题目链接

Zhejiang University has 8 campuses and a lot of gates. From each gate we can collect the in/out times and the plate numbers of the cars crossing the gate. Now with all the information available, you are supposed to tell, at any specific time point, the number of cars parking on campus, and at the end of the day find the cars that have parked for the longest time period.

Input Specification:

Each input file contains one test case. Each case starts with two positive integers N ( ≤ 10 ​ 4 ) N (≤10​^4) N(104), the number of records, and K ( ≤ 8 × 1 0 4 ) K (≤8×10^4) K(8×104) the number of queries. Then N lines follow, each gives a record in the format:

plate_number hh:mm:ss status

where plate_number is a string of 7 English capital letters or 1-digit numbers; hh:mm:ss represents the time point in a day by hour:minute:second, with the earliest time being 00:00:00 and the latest 23:59:59; and status is either in or out.

Note that all times will be within a single day. Each in record is paired with the chronologically next record for the same car provided it is an out record. Any in records that are not paired with an out record are ignored, as are out records not paired with an in record. It is guaranteed that at least one car is well paired in the input, and no car is both in and out at the same moment. Times are recorded using a 24-hour clock.

Then K lines of queries follow, each gives a time point in the format hh:mm:ss. Note: the queries are given in ascending order of the times.

Output Specification:

For each query, output in a line the total number of cars parking on campus. The last line of output is supposed to give the plate number of the car that has parked for the longest time period, and the corresponding time length. If such a car is not unique, then output all of their plate numbers in a line in alphabetical order, separated by a space.

题意

给定一个 n ( n ≤ 1 0 4 ) n(n\leq 10^4) n(n104) q ( q ≤ 8 ∗ 1 0 4 ) q(q\leq 8*10^4) q(q8104),表示停车记录数量和询问数量。
给你 n n n 个停车记录,包括车牌号,停车时间,停车状态。

车牌号为 7 7 7 位,由大写字母和数字组成
停车时间格式为 h h : m m : s s hh:mm:ss hh:mm:ss
停车状态为开入和开出 ( i n   o r   o u t ) (in\ or\ out) (in or out)

任何未与输出记录配对的输入记录都将被忽略,未与输入记录配对的输出记录也将被忽略。也就是说多个 i n in in 只算最后一个,多个 o u t out out 算第一个, i n   o u t   i n   o u t in\ out\ in\ out in out in out 这种是符合而且算两次停车,这个车牌号的停车时间应该等于这两段相加。

然后有 q q q 次询问,每次询问一个时间 t t t ,输出 t t t 时车库中有多少辆车。
最后一行输出停车时长最久的车,若有多辆,按字符串大小输出,小的优先,然后再输出停车时长。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
struct node {
    char s[50];  // 车牌
    int t, st;   // 时间和出入状态 in 为 1
} p[N], w[N];  // p数组存储输入信息
char s[50], ans[N][50]; // ans存储最大时间的车牌
bool cmp1(node a, node b) {
    int v = strcmp(a.s, b.s);  // 比较两个字符串的函数 v < 0 表示前一个小
    if(v < 0) return true;
    else if(v > 0) return false;
    return a.t < b.t;
}
int n, q, h, f, m;
int k, cnt, maxn;  // k 表示有效停车的车牌数  cnt表示停车时间最长的车牌数  maxn为最长停车时间
int c[N], sum[N];
int main() {
    scanf("%d%d", &n, &q);  // 记录和询问
    for(int i = 1;i <= n;i++) {
        scanf("%s %d:%d:%d %s", p[i].s, &h, &f, &m, s); //车牌号 时分秒 状态
        p[i].t = h * 3600 + f * 60 + m;   // 时间转换
        if(s[0] == 'i') p[i].st = 1;
    }
    sort(p + 1, p + n + 1, cmp1);   // 基于车牌号排序  相同的按照时间排序
    for(int i = 1;i <= n;i++) {
        if(strcmp(p[i].s, p[i + 1].s) == 0 && p[i].st == 1 && p[i + 1].st == 0) {
            // 若车牌号相同 而且前一个为进 后一个出则为有效停车
            int id = k + 1;
            for(int j = 1;j <= k;j++) {   // 遍历之前的有效信息 若车牌号相同  停车时间相加
                if(strcmp(p[i].s, w[j].s) == 0) {
                    w[j].t += p[i + 1].t - p[i].t;
                    id = j;
                    break;
                }
            }
            if(id == k + 1) {   // 若没有 则新创一个停车记录
                w[++k].t = p[i + 1].t - p[i].t;
                strcpy(w[k].s, p[i].s);
            }
            if(w[id].t > maxn) {   // 更新停车时间最大值
                maxn = w[id].t;
                cnt = 0;
            }
            if(w[id].t == maxn) strcpy(ans[++cnt], w[id].s);  // 若为最大值  则进入ans数组
            c[p[i].t]++;   // 差分数组 24 * 3600 = 86400 为时间最大值
            c[p[i + 1].t]--;
        }
    }
    for(int i = 0;i < N;i++) sum[i] = sum[i - 1] + c[i];   // 差分数组前缀和处理出当前时间i时的停车数量
    while(q--) {
        scanf("%d:%d:%d", &h, &f, &m);
        printf("%d\n", sum[h * 3600 + f * 60 + m]);
    }
    for(int i = 1;i <= cnt;i++) printf("%s ", ans[i]);  // 输出停车时间最大值的车牌
    printf("%02d:%02d:%02d\n", maxn / 3600, maxn % 3600 / 60, maxn % 60);   // 输出停车时间
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

he_69

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值