PAT甲级 1095 Cars on Campus (30分) map/C++

1095 Cars on Campus (30分)

题目大意:给定车的进出时间,要求去掉不合法的数据(只有进没有出,只有出没有进)。问query中的时间点校园内有多少辆车,并且输出在校园中停留时间最长的车序列。

这道题真的很需要耐心和细心,考察stl的使用

捋一捋思路:

  1. 去掉不合法的数据,也就是in和out要配对:先对时间进行排序,排完以后必定是一进一出配对的出现,如果不成对出现则舍弃;
  2. 计算停留时间最长的车:在去掉不合法数据的同时,计算其停留时间,使用map来存放,以便下一次直接找到并增加停留时长;
  3. 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会报错
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值