PAT-A 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​​), the number of records, and K (≤8×10​4​​) 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 inrecord. 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.

Sample Input:

16 7
JH007BD 18:00:01 in
ZD00001 11:30:08 out
DB8888A 13:00:00 out
ZA3Q625 23:59:50 out
ZA133CH 10:23:00 in
ZD00001 04:09:59 in
JH007BD 05:09:59 in
ZA3Q625 11:42:01 out
JH007BD 05:10:33 in
ZA3Q625 06:30:50 in
JH007BD 12:23:42 out
ZA3Q625 23:55:00 in
JH007BD 12:24:23 out
ZA133CH 17:11:22 out
JH007BD 18:07:01 out
DB8888A 06:30:50 in
05:10:00
06:30:50
11:00:00
12:23:42
14:00:00
18:00:00
23:59:00

Sample Output:

1
4
5
2
1
0
1
JH007BD ZD00001 07:20:09
#include <cstdio>
#include <map>
#include <string>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;

typedef struct record
{
    char id[8];//车牌号
    char time[9];
    char status[4];//in or out
}record;

bool cmpByIdAndTime(record a, record b)
{   //通过Id和时间进行排序
    int t = strcmp(a.id, b.id);
    if(t != 0)
        return t < 0;
    else
        return strcmp(a.time, b.time) < 0;
}

bool cmpByTime(record a, record b)
{   //只按照时间进行排序
    return strcmp(a.time, b.time) < 0;
}
//计算两个给定表示时间的字符串,返回这两个时间之间的秒数
int timeToSecond(char* t1, char* t2)
{
    int h1, m1, s1;
    int h2, m2, s2;
    sscanf(t1, "%d:%d:%d", &h1, &m1, &s1);
    sscanf(t2, "%d:%d:%d", &h2, &m2, &s2);
    return (h2 - h1) * 3600 + (m2 - m1) * 60 + s2 - s1;
}
//给定一个表示时长的秒数,转化为表示时间的字符串,并保存在time中
void secondToTime(char* time, int second)
{
    int h = second / 3600;
    int m = second % 3600 / 60;
    int s = second % 60;
    sprintf(time, "%02d:%02d:%02d", h, m, s);
}
int main()
{
    int n;//the number of records
    int k;//the number of queries
    scanf("%d %d", &n, &k);

    record all[n];//所有的停车记录
    map<string, int> car;//车牌号->停车时间
    for(int i = 0; i < n; i++)
    {
        scanf("%s %s %s", all[i].id, all[i].time, all[i].status);
        car[string(all[i].id)] = 0;//停车时间初始化为0
    }
    sort(all, all + n, cmpByIdAndTime);//通过ID和时间进行排序
    int maxTime = 0;//最长的停车时间
    vector<record> valid;//有效的停车记录
    for(int i = 0; i < n; i++)//遍历每个停车记录
    {
        if(all[i].status[0] == 'i')//该条记录是in
        {
            if(i + 1 < n && strcmp(all[i].id, all[i + 1].id) == 0)//还有下一个记录,并且是同一辆车的记录
            {
                    if(all[i + 1].status[0] == 'o')//匹配成功
                    {
                        string tempId(all[i].id);
                        car[tempId] += timeToSecond(all[i].time, all[i + 1].time);//更新该车的停车时间
                        if(car[tempId] > maxTime)
                            maxTime = car[tempId];//更新最长停车时间
                        valid.push_back(all[i]);//保存有效的停车记录
                        valid.push_back(all[i + 1]);
                    }
            }
        }
    }
    //现在所有有效车的停车时长在car中,有效记录存储在valid中
    sort(valid.begin(), valid.end(), cmpByTime);//通过时间对有效记录进行排序
    char time[10];//保存一个形如"hh:mm:ss"的字符串
    //由于题目保证查询时刻有序,所以这两个变量可以定义在外面,减少运行时间
    int nowNum = 0;//校园里的停车数量
    int index = 0;//当前遍历到的停车记录
    for(int i = 0; i < k; i++)
    {
        scanf("%s", time);//待查询的时刻
        while(index < valid.size() && strcmp(time, valid[index].time) >= 0)
        {
            if(valid[index].status[0] == 'i')//in
                nowNum++;
            else //out
                nowNum--;
            index++;//遍历下一个停车记录
        }
        printf("%d\n", nowNum);//输出当前时刻的停车数量
    }
    for(auto it = car.begin(); it != car.end(); it++)
    {
        if(it->second == maxTime)
            printf("%s ", it->first.c_str());
    }
    secondToTime(time, maxTime);//将最长停车时间的秒数转换成字符串
    printf("%s\n", time);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38127801/article/details/86506099