【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刷

代码

cpp 复制代码
/**
 * 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;
}
相关推荐
木木子225 小时前
# 密码强度检测深度解析:正则表达式实时分析、多维度评分算法与可视化反馈
mysql·算法·华为·正则表达式·harmonyos
Sw1zzle8 小时前
算法入门(四):二叉树 - 递归遍历三件套
算法·leetcode
万法若空8 小时前
【算法-查找】查找算法
java·数据结构·算法
海石8 小时前
子树怎么找?树的3种遍历方式来帮忙!
算法·leetcode
海石8 小时前
难度分 1588:思路 + 技巧 = AC
算法·leetcode
殳翰8 小时前
下服务器端开发流程及相关工具介绍(C++)
开发语言·c++
青瓦梦滋9 小时前
协议定制/序列化-反序列化(Linux视角)
linux·服务器·网络·c++
珠海西格电力12 小时前
云边端协同架构:零碳园区管理系统的技术底座
大数据·运维·人工智能·算法·架构·能源
山登绝顶我为峰 3(^v^)313 小时前
C/C++ 交叉编译方法
java·c语言·c++
还有多久拿退休金14 小时前
让飞书知识库跟着 commit 自己长:一套自动化知识库的真实实现
前端·算法·架构