【PAT】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.

翻译:浙江大学有8个校区和许多校门。从每个校门我们可以统计每辆车进出大门的时间。现在我们获得了所有的信息,你需要说出在任何一个特定的时间节点下停放在校园里的汽车数量,并且找出那些停放最长时间的车辆。

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×104) 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.

翻译:每个输入文件包含一组测试数据。对于每组输入数据,开始包括两个正整数 N(≤10​4), 表示记录数, 和 K(≤8×104),表示查询数。接下来的N行,每行记录按照以下格式给出:
车牌号 hh:mm:ss 状态
车牌号由一个7位的英文大写字符或1位数字组成,hh:mm:ss用的时:分:秒表示一天的时间,最早为00:00:00并且最晚为23:59:59。状态为进或者出。
注意所有时间都是同一天的。每一条驶入记录都与同一辆车最近的驶出记录相匹配。任意一条没有匹配的记录都会被舍弃。数据保证输入数据中至少有一辆车是有匹配记录的,并且没有车在同一时间同时有驶入和驶出记录。时间为24时制记录。
接下来有K行查询,每一行按照hh:mm:ss的格式给出一个时间节点。注意:查询的时间按升序排列。

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


解题思路

这道题的核心为去噪和模拟驶入驶出。去噪难度不大,在此不细说,当看到题目多组查询的时候,我的第一反应就是用树状数组,这道题不就是典型的区间修改、单点查询吗,然后兴冲冲打了个BIT模板,然后提交超时。。。然后仔细看了一下题目发现查询时间按照升序排列, 所以直接模拟车辆进出即可,先去掉多余数据,然后将正确数据压入vector,按照时间轴排序,然后进行模拟,如果为in则车辆数加一,如果为out则车辆数减一。当查询时间小于当前时间时则输出车辆数。详见代码。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
#include<iomanip>
#define INF 99999999
#define bug puts("Hello\n")
using namespace std;
map<string,int>mp;//将车牌用map转化成数字 
vector<string>carName;//保存map对应的车牌 
typedef pair<int,int> P;
int carCount=1;//记录车数 
vector<P>car[10010];//保存车的进出,用于消除非法数据 
vector<string>Longest;//保存最长停车时间的车牌

bool cmp(P a,P b){
	return a.first<b.first;
}

int N,K; 

struct TimeNode{
    int time;
    int type;//1为进,2为出 
	TimeNode(int Time,int Type):time(Time),type(Type){} 
    bool operator<(const TimeNode &a)const{
        return time==a.time?type>a.type:time>a.time;
    } 
};
priority_queue<TimeNode>TimeBase;//时间轴  
int tmpcarCount=0;//记录当前用户的车辆数  

int main(){
	scanf("%d %d",&N,&K);
	for(int i=0;i<N;i++){
		string tmpCar;
		char tmpFlag[4];
		int h,m,s,tflag;
		char c=getchar();
		cin>>tmpCar;
		scanf("%d:%d:%d %s",&h,&m,&s,tmpFlag);
		if(strcmp(tmpFlag,"in")==0)tflag=1;
		else tflag=0;
		if(!mp[tmpCar])mp[tmpCar]=carCount,carName.push_back(tmpCar),carCount++;
		car[mp[tmpCar]].push_back(P(h*3600+m*60+s,tflag));
	} 
	int LongestTime=0;
	for(int i=1;i<=carCount;i++){
		sort(car[i].begin(),car[i].end(),cmp);
		int length=0;
		for(int j=0;j<car[i].size();j++){
			if(j+1<car[i].size()&&car[i][j].second==1&&car[i][j+1].second==0){
				length+=car[i][j+1].first-car[i][j].first;
				TimeBase.push(TimeNode(car[i][j].first,1));
				TimeBase.push(TimeNode(car[i][j+1].first,2));
			}
		} 
		if(LongestTime<length){
			LongestTime=length;
			Longest.clear();
			Longest.push_back(carName[i-1]);
		}	
		else if(LongestTime==length){
			Longest.push_back(carName[i-1]);
		}
	}
	for(int i=0;i<K;i++){
		int h,m,s;
		scanf("%d:%d:%d",&h,&m,&s);
		int query=h*3600+m*60+s;
		while(!TimeBase.empty()){
			TimeNode tmp=TimeBase.top();
			if(tmp.time<=query){
				if(tmp.type==1)tmpcarCount++;
				else if(tmp.type==2)tmpcarCount--;
				TimeBase.pop(); 
			}else break;
		}
		printf("%d\n",tmpcarCount);
	}
	
	for(int i=0;i<Longest.size();i++){
		cout<<Longest[i]<<" ";
	}    
	printf("%02d:%02d:%02d\n",LongestTime/3600,(LongestTime/60)%60,LongestTime%60);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值