1095 Cars on Campus (30分)
题目大意:给定车的进出时间,要求去掉不合法的数据(只有进没有出,只有出没有进)。问query中的时间点校园内有多少辆车,并且输出在校园中停留时间最长的车序列。
这道题真的很需要耐心和细心,考察stl的使用
捋一捋思路:
- 去掉不合法的数据,也就是in和out要配对:先对时间进行排序,排完以后必定是一进一出配对的出现,如果不成对出现则舍弃;
- 计算停留时间最长的车:在去掉不合法数据的同时,计算其停留时间,使用map来存放,以便下一次直接找到并增加停留时长;
- query时间点校园内有多少辆车:对合法的车序列按照时间先后进行排序,如果在该时间点之前并且为in,则数量+1,如果状态为out,则数量-1;这里由于query的时间是按照顺序排序的,所以对于车序列的遍历只需要一趟即可。
#include<iostream> //输入输出流头文件
#include<algorithm> //C++标准模板库的函数
#include<map> //map映射容器
#include<vector> //变长数组容器
#include<string> //C++string类
using namespace std; //标准命名空间
int n,k,num=0,ind=0,maxtime=0,h,m,s;
struct cars{
string plate,status;
int time;
cars(string plate,int time,string status):plate(plate),time(time),status(status){}
cars(){}
};
bool cmp1(cars a,cars b){//把同一车牌的序列按照时间顺序排列
return a.plate!=b.plate?a.plate<b.plate:a.time<b.time;
}
bool cmp(cars a,cars b){
return a.time<b.time;
}
int main(){ //主函数
vector<cars> car,yescar;
vector<string> maxtimeindex;
cin>>n>>k;
for(int i=0;i<n;i++){
string p=" ",st=" ";
scanf("%s %d:%d:%d %s",&p[0],&h,&m,&s,&st[0]);
int t=3600*h+60*m+s;//把时间转换为秒
car.push_back(cars(p,t,st));
}
map<string,int> parttime;
sort(car.begin(),car.end(),cmp1);
for(int i=0;i<n-1;i++){
if(car[i].status=="in"&&car[i+1].status=="ou"&&car[i].plate==car[i+1].plate){
parttime[car[i].plate]+=(car[i+1].time-car[i].time);//记录总的停留时长
if(maxtime<parttime[car[i].plate]) {//更新
maxtime= parttime[car[i].plate];
maxtimeindex.clear();
maxtimeindex.push_back(car[i].plate);
}
else if(maxtime==parttime[car[i].plate])maxtimeindex.push_back(car[i].plate);
yescar.push_back(car[i]);
yescar.push_back(car[i+1]);
i++;
}
}
sort(yescar.begin(),yescar.end(),cmp);//按时间先后排序
for(int j=0;j<k;j++){
scanf("%d:%d:%d",&h,&m,&s);
int t=3600*h+60*m+s;
for(;ind<n;ind++){
if(yescar[ind].time<=t){//在该时间之前进入校园
if(yescar[ind].status=="in") num++;
else num--;//在改时间之前出校园
}
else break;
}
cout<<num<<endl;
}
for(int i=0;i<maxtimeindex.size();i++)cout<<maxtimeindex[i]<<' ';
printf("%02d:%02d:%02d\n",maxtime/3600,maxtime%3600/60,maxtime%3600%60);
return 0; //返回0,如果不返回0,PAT会报错
}