[code] PTA 胡凡算法笔记 DAY022

题目 A1095 Cars on Campus

在这里插入图片描述

  • 题意
    去除无效记录,然后根据查询时间点给出停车场停车数量及今天一天停车时间最长的车的编号及时长。

  • 思路
    主要需要实现几个功能:过滤无效信息,判断时间区间,获取每个车的停车时间然后取最大值。
    过滤无效信息。先将记录以id和时间排序,这样相同车牌号的记录会按时间顺序排在一起。就可以直接以前后是否为in, 'out’判断是否有效。
    判断时间区间。为了方便时间判断,时间的处理采用都以秒为基本单位计算。因为记录都是按时间排序输入的,所以可以将有效信息记录以时间从低到高排序,用一个下标去指示目前已经判断到的时间点。然后就按停车场的逻辑来处理,in 加一,out减一。
    获取车牌及最大停车时长。这里需要用map存储id和停车时长的映射。在遍历筛选无效信息的时候就可以处理。

  • Code in C++

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>

const int MAXN = 10001;
struct Car {
    char id[8];
    int time;
    char status[4];
}cars[MAXN], valid[MAXN];

bool cmp(const Car &a, const Car &b) {
    if (strcmp(a.id, b.id)) return strcmp(a.id, b.id) < 0;
    else return a.time < b.time;
}

bool cmpt(const Car &a, const Car &b) {
    return a.time < b.time;
}

int allTime(int hh, int mm, int ss) {
    return hh * 3600 + mm * 60 + ss;
}

int validCount = 0;
std::map<std::string, int> parkTime;
int main()
{
    int n, k, hh, mm, ss;
    scanf("%d %d", &n, &k);
    for (int i = 0; i < n; ++i) {
        scanf("%s %d:%d:%d %s", cars[i].id, &hh, &mm, &ss, cars[i].status);
        cars[i].time = allTime(hh, mm, ss);
    }
    std::sort(cars, cars + n, cmp);
    int maxTime = -1;  // 记录最长时间
    for (int i = 0; i < n - 1; ++i) {
        if (!strcmp(cars[i].id, cars[i+1].id) &&
            !strcmp(cars[i].status, "in") &&
            !strcmp(cars[i+1].status, "out")) {
                valid[validCount++] = cars[i];
                valid[validCount++] = cars[i + 1];
                if (parkTime.count(cars[i].id) == 0) {
                    parkTime[cars[i].id] = 0;
                }
                parkTime[cars[i].id] = parkTime[cars[i].id] + (cars[i+1].time - cars[i].time);
                maxTime = std::max(maxTime, parkTime[cars[i].id]);
            }
    }
    std::sort(valid, valid + validCount, cmpt);
    int now = 0, carNum = 0;
    for (int i = 0; i < k; ++i) {
        scanf("%d:%d:%d", &hh, &mm, &ss);
        int query = allTime(hh, mm, ss);
        while (now < validCount && valid[now].time <= query) {
            if (!strcmp(valid[now].status, "in")) ++carNum;
            else --carNum;
            ++now;
        }
        printf("%d\n", carNum);
    }

    for (auto it = parkTime.begin(); it != parkTime.end(); ++it) {
        if (it->second == maxTime) printf("%s ", it->first.c_str());
    }


    printf("%02d:%02d:%02d", maxTime / 3600, maxTime % 3600 / 60, maxTime % 60);
    return 0;
}


小结

① 今天做这题考虑复杂了,对于时间的处理还设置了一个结构体,写了运算符重载等等函数(不过也算是复习了一下怎么写)。
② 然后有效信息没有用另外一个数组存储而是直接用flag去记的,所以混在一起处理有点棘手。
③ 对于时间段查询,应该采用模拟实际的思路进行并且充分利用题目所给的时间排好序的条件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值