PAT(甲级)渡劫(六)-Cars on Campus(30)
题目大意:
题意:给出n个车辆进出校园的记录,以及k个时间点,让你回答每个时间点校园内的车辆数,最后输出在校园内停留的总时间最长的车牌号和停留时间,如果不止一个,车牌号按字典序输出。
几个注意点:
1.如果一个车连续多次进入,只取最后一个
2.如果一个车连续多次出去,只取第一个
3.一个车可能出入校园内好几次,停留时间取总和
算法思想:
注意题目所给的信息,k个queries是按时间降序给出的,所以我们遍历时只要对所有记录按照时间排序,再进行遍历即可;否则容易超时
注意in和out的配对,本代码用islegal来核对该条记录是否正确;
对于最大值对应车牌号的储存,用string来记录所有满足条件的车牌号比较方便;
注意最后时间格式的输出;
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
struct node{
char plate[12]; // 车牌号
int time;
int status;
bool islegal;
}v[10008];
bool sortbyplate(const node &a,const node &b){
if(strcmp(a.plate,b.plate) == 0)
return a.time < b.time;
return strcmp(a.plate,b.plate) < 0;
}
bool sortbytime(const node &a,const node &b){
if(a.islegal == b.islegal)
return a.time < b.time;
return a.islegal > b.islegal;
}
void CheckIslegal(struct node v[],int n){
for(int i = 0 ; i < n ; i++){
if(i == n-1){
v[i].islegal = false;
break;
}
if(strcmp(v[i].plate,v[i+1].plate) == 0){
if(v[i].status && !v[i+1].status){ // 若车一进一出,则合法
v[i].islegal = true;
v[i+1].islegal = true;
i++; // 跳过已经检查的两台车
}else // 否则不合法
v[i].islegal = false;
}
}
}
int CalMaxtime(struct node v[],int n,string &ans){
int max = -1;
for(int i = 0 ; i < n ; i++){
if(v[i].islegal && v[i].status){
int ct = 0,j = i; // ct统计停车时间,j用于计算一辆车的多次进出入
while(j < n && strcmp(v[i].plate,v[j].plate) == 0){
if(v[j].islegal && v[j].status){
ct += v[j+1].time - v[j].time;
++j;
}
++j; // 两次j++,跳过已经检查的两辆车
}
if(max < ct){
ans.clear();
ans = v[i].plate;
max = ct;
}else if(max == ct){
ans += " "; // 若有多辆
ans += v[i].plate;
}
i = j-1; // 跳过多台已经检查的车
}
}
return max;
}
void ReadQuery(struct node v[],int n,int k){
int hh,mm,ss,cur,i = 0,cnt = 0;
while(k--){
scanf("%d:%d:%d",&hh,&mm,&ss);
cur = hh*3600+mm*60+ss;
while(i < n && v[i].time <= cur && v[i].islegal){
if(v[i].status) ++cnt; // 若车进去,则车辆数加1
else --cnt; // 若车出去,则车辆数减1
++i;
}
printf("%d\n",cnt); // 输出此时间段的车辆数
}
}
int main(){
freopen("in.txt","r",stdin);
int n,k;
int hh,mm,ss;
char s[8];
scanf("%d%d",&n,&k);
for(int i = 0 ; i < n ; i++){ // 输入车牌号,时间以及状态
scanf("%s %d:%d:%d %s",v[i].plate,&hh,&mm,&ss,s);
v[i].time = hh*3600 + mm*60 + ss;
v[i].status = (s[0] == 'i')?1:0;
}
sort(v,v+n,sortbyplate); // 根据车牌号排序
CheckIslegal(v,n);
string ans = "";
int max = CalMaxtime(v,n,ans);
sort(v,v+n,sortbytime);
ReadQuery(v,n,k); // k条查询
printf("%s %02d:%02d:%02d",ans.c_str(),max/3600,max%3600/60,max%60);
return 0;
}