题目 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
去记的,所以混在一起处理有点棘手。
③ 对于时间段查询,应该采用模拟实际的思路进行并且充分利用题目所给的时间排好序的条件。