关注

【PAT甲级真题】- Cars on Campus (30)

题目来源

Cars on Campus (30)-牛客
Cars on Campus (30)-PTA

注意点:

  • 牛客的答案有错!!!!!去PTA上面测
  • out 的时间表示车辆已经出去
  • 输入是乱序,按照题目要求应该按时间顺序排序
  • 最后的最长停靠时间输出按字典序

题目描述

Zhejiang University has 6 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.

输入描述:

Each input file contains one test case. Each case starts with two positive integers N (<= 10000), the number of records, and K (<= 80000) 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.

输出描述:

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.

输入例子:

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

输出例子:

1
4
5
2
1
0
1
JH007BD ZD00001 07:20:09

思路简介

一道经典的差分+模拟

首先按照题目的要求要先对时间进行排序

对于模拟的部分,主要是时间的统计:
只要用一个map记录车辆的 in 时间即可,对于一个 out记录

  • 如果有 in记录 ,就计算并清掉 in 记录
  • 如果没有 in 记录说明不合法

这里注意几点

  • 车辆停泊的时间算的是总时间,也就是同一辆车一天内多次进出停车场的时间总和
  • out 记录的时间点是车辆已经出去的时间结点

对于差分的部分:
其实就是在匹配到合法的 out 之后,给时间数组的 in 记录位置 +1,out 记录位置 -1
然后最后求前缀和,就可以得到每秒的停车数

这里注意

  • 同一时间内可能有多辆车进出停车场

遇到的问题

  1. 看错题目了,以为一辆车一天只能进出一次,其他记录不合法
  2. 改过来之后应该是一遍过的

但是牛客是真的神秘,明明是陈年老题了也有纠错功能,但是答案居然真还是错的,我硬生生调了三个小时,一直没去想是不是答案的问题
后面逛评论区发现有人说补 70000 行 0 就可以过了
我试了一下发现真行,也是服气了。。。

其实早早去PTA上面刷题就行了
但是一开始我是在牛客上做的,还是先做完在去PTA刷

代码

/**
 * https://www.nowcoder.com/pat/5/problem/4319
 * 差分
 */
#include<bits/stdc++.h>
using namespace std;

const int N=2e5;

struct Record{
    string plate,time,t;

    Record():plate(""),time(""),t(""){}
    Record(string plate,string time,string t):plate(plate),time(time),t(t){}
    bool operator<(const Record& a){
        return this->time<a.time;
    }
};

//记录车的停靠总时间和进入时间
map<string,int>port_time,intime;

int time_num[N];

int n,m;

int time_to_sec(string str){
    istringstream ss(str);
    int h,m,s;
    char c;
    ss>>h>>c>>m>>c>>s;
    return h*3600+m*60+s;
}

string sec_to_time(int sec){
    int h = sec / 3600;
    int m = (sec % 3600) / 60;
    int s = sec % 60;
    char buffer[10];
    sprintf(buffer, "%02d:%02d:%02d", h, m, s);
    return string(buffer);
}

vector<string>longest_port;
int maxtime=0;

void input(){
    cin>>n>>m;
    vector<Record>v(n);
    for(int i=0;i<n;++i){
        cin>>v[i].plate>>v[i].time>>v[i].t;
    }

    sort(v.begin(),v.end());
    //for(auto r:v)cout<<r.plate<<' '<<r.t<<' '<<r.time<<'\n';

    for(auto r:v){
        string plate=r.plate,t=r.t,time=r.time;

        if(t=="in"){//in记录
            //直接更新intime
            intime[plate]=time_to_sec(time);
        }
        else{
            if(!intime.count(plate))continue;//没有对应的in记录

            int sec=time_to_sec(time);
            time_num[sec]-=1;
            time_num[intime[plate]]+=1;
            int len=sec-intime[plate];

            intime.erase(plate);

            port_time[plate]+=len;
            if(port_time[plate]>maxtime){
                maxtime=port_time[plate];
                longest_port.clear();
                longest_port.emplace_back(plate);
            }
            else if(port_time[plate]==maxtime){
                longest_port.emplace_back(plate);
            }
        }
    }
    
    for(int i=1;i<N;++i){
        time_num[i]+=time_num[i-1];
    }
}

void output(){
    int len=longest_port.size();
    sort(longest_port.begin(),longest_port.end());
    for(auto x:longest_port){
        cout<<x<<' ';
    }
    cout<<sec_to_time(maxtime)<<'\n';
}

void solve(){
    string q;
    cin>>q;
    int sec=time_to_sec(q);
    cout<<time_num[sec]<<'\n';
}

int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //fstream in("in.txt",ios::in);cin.rdbuf(in.rdbuf());

    input();

    while(m--){
        solve();
    }
    //for(int i=0;i<70000;++i)cout<<0<<'\n';//牛客提交补0
    output();
    
    //cout<<'\n'<<sec_to_time(-time_to_sec("05:10:33")+time_to_sec("12:23:42"));
    return 0;
}

转载自CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/ppparaneciym/article/details/160155209

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--