解题思路:
两轮排序。第一轮筛选出有效的停车记录,然后统计每辆车的时间。第二轮按记录的时间排序,可以按时间计算当前的车辆数。
把时间转换成秒,会方便很多。
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
using namespace std;
const int maxn = 10000 + 5;
struct Record
{
int in; //进入还是退出
int flag; //记录有效性
int time; //记录的时间
char carNum[10];
} record[maxn];
int n, q;
map<string, int> carIDtoParkTime;//保存停车时间
bool cmp1(Record a, Record b)
{
if(strcmp(a.carNum, b.carNum) != 0)
return strcmp(a.carNum, b.carNum) < 0;
return a.time < b.time;
}
bool cmp2(Record a, Record b)
{
if(a.flag != b.flag)
return a.flag > b.flag;
else return a.time < b.time;
}
int main()
{
while(scanf("%d%d", &n, &q) == 2)
{
for(int i = 0; i < n; i++)
{
int hh, mm, ss;
scanf("%s", record[i].carNum);
scanf("%d:%d:%d", &hh, &mm, &ss);
record[i].time = hh * 3600 + mm * 60 + ss;
char status[5];
scanf("%s", status);
if(status[0] == 'i') record[i].in = 1;
else record[i].in = 0;
record[i].flag = 0;
}
sort(record, record + n, cmp1);
int maxt = 0;
for(int i = 0; i < n; i++)
{
Record& a = record[i];
Record& b = record[i+1];
if(strcmp(a.carNum, b.carNum) == 0 && a.in == 1 && b.in == 0)
{
a.flag = 1;
b.flag = 1;
string s(a.carNum);
if(carIDtoParkTime.count(s))
{
carIDtoParkTime[s] += b.time - a.time;
maxt = max(maxt, carIDtoParkTime[s]);
}
else
{
carIDtoParkTime[s] = b.time - a.time;
maxt = max(maxt, carIDtoParkTime[s]);
}
}
}
sort(record, record+n, cmp2);
int num = 0, p = 0;
for(int i = 0; i < q; i++)
{
int hh, mm, ss;
scanf("%d:%d:%d", &hh, &mm, &ss);
int t = hh * 3600 + mm * 60 + ss;
while(record[p].time <= t && record[p].flag)
{
if(record[p].in) num++;
else num--;
p++;
}
printf("%d\n", num);
}
for(map<string, int>::iterator it = carIDtoParkTime.begin(); it != carIDtoParkTime.end(); ++it)
{
if(it->second == maxt)
printf("%s ", it->first.c_str());
}
printf("%02d:%02d:%02d\n", maxt/3600, maxt%3600/60, maxt%60);
}
return 0;
}