给出N条记录,每条记录给出一辆车的车牌号、当前时刻以及出入校状况(入校(in)仍是出校out))。而后给出K个查询,每一个查询给出一个时刻,输出在这个时刻校园内的车辆数。查询完毕后输出在学校内停留时间最长的车辆的车牌号(若是有多个,就一并输出)和
对应的停留时间。算法
该题和1016 Phone Bills的数据处理要求很类似, 这里要求给定某一个时刻,要求当前时刻有多少辆车在停车场,最直观的想法就是用一个变量(car_num)来记录车辆数目,从开始时刻到查询时刻,遇到in的记录就加一,遇到out的时候就减一,而后就获得当前查询时刻有多少车辆存在停车场了,可是该使用方法有一个前提条件,那就是全部的记录都得是有效记录,可是这里的记录有多是无效的,因此,第一件事就是将记录全部的有效记录所有筛选出来存放在valid_records数组中,而后对于对于每一次查询就能够按照上述方法得到车辆数目,对于最长的停车时间长度能够在筛选有效记录的时候记录最长的停车时间和对应的车牌号码。数组
首先按照车牌号分组,按照字典序排序,对于车牌号相同的按照时间前后排序,这是为了筛选有效记录。
按照时间前后排序。
先按照排序规则一进行排序,使用指针i遍历全部的记录,这里的i最大为N-2,由于有效记录为一对,因此i<N-1便可。首先得判断i和i+1条记录为同一辆车的记录,不然无心义,而后再判断i和i+1的status分别为in和out,这样的记录才是一对有效记录,对于每一条有效记录,咱们将i和i+1添加进valid_records数组中,而后再累计该车辆的停车时间,这里使用map<string,int> cars进行存储每一辆车对应的累计停车时间,
最后在记录最大的停车时长便可(用max_parking_time记录)测试
先按照排序规则2排序,而后咱们注意到查询的时刻是依次递增的,也就是说,若是每一次查询都是从都开始查询的话,会和上一次查询的记录重复,能够采起紧接着上一次查询位置日后查询车辆进出状况的方法,咱们使用index记录上一次查询的记录位置,初始为0,使用car_num记录上一次查询停车场车辆的停留数目,只要当前index指向的记录的时间<=查询时间,那么就重复如下操做:spa
一、若是index指向记录的status为in,car_num++; 二、若是index指向记录的status为out,car_num--;
一、对同一辆车来讲,配对的on和off必须知足在把这辆车的记录按时间顺序排列后,在它们之间不容许出现其余on或者off的记录;不然,将被视为无效记录。 二、若是每一次查询都是从00:00:00开始查询的话,会超时。 三、有可能查询时间在全部记录时刻以后,好比查询为23:59:59,可是记录的最靠后的时间为20:00:00,那么index得判断是否将valid_records遍历完毕了。测试点1和2考察该点(本身测试获得的结果,不必定准确)
#include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include<map> using namespace std; struct Record{ string plate_number ;//车牌号码 int time; bool status;// in为true,out为false }; int getSeconds(int hh,int mm,int ss){ return hh*3600+mm*60+ss; } bool cmp(Record a,Record b){ if(a.plate_number!=b.plate_number){ return a.plate_number<b.plate_number; }else{ return a.time<b.time; } } bool cmpByTime(Record a,Record b){ return a.time<b.time; } int main(){ int N,K;//记录总数和查询总数 scanf("%d %d",&N,&K); vector<Record> records; Record record; char plate_number[20]; int hh,mm,ss; char status[10]; for(int i=0;i<N;++i){ scanf("%s %d:%d:%d %s",plate_number,&hh,&mm,&ss,status); record.plate_number = plate_number; record.time = getSeconds(hh,mm,ss); record.status = strcmp(status,"in")==0; records.push_back(record); } sort(records.begin(),records.end(),cmp); //筛选无效记录 map<string,int> cars;//每一辆车停车的最长时间 int max_parking_time = -1;//最长停车时间 vector<Record> valid_records; int begin=0,next=0; for(int i=0;i<N-1;++i){ if(records[i].plate_number==records[i+1].plate_number){ // i和i+1是同一辆车 if(records[i].status&&!records[i+1].status){ //i为in,i+1为out,i与i+1为一对有效记录 valid_records.push_back(records[i]); valid_records.push_back(records[i+1]); int parking_time = records[i+1].time-records[i].time;//停车时间 // 更新该辆车的累计停车时间 cars[records[i].plate_number] += parking_time; max_parking_time = max_parking_time<cars[records[i].plate_number]?cars[records[i].plate_number]:max_parking_time;//更新全部车辆最长停车时间 } } } //根据时间进行排序 sort(valid_records.begin(),valid_records.end(),cmpByTime); //查询开始 int index = 0;//当前查询记录的下标 int car_num = 0;//当前停车场的车辆数目 for(int i=0;i<K;++i){ scanf("%d:%d:%d",&hh,&mm,&ss); int query_time = getSeconds(hh,mm,ss); // 从index一直找到停车时间大于query_time的前面一辆记录便可 while(index<valid_records.size()&&valid_records[index].time<=query_time){ if(valid_records[index].status){ ++car_num; }else{ --car_num; } ++index; } printf("%d\n",car_num); } //输出最长停车时间的车牌号和时间 map<string,int>::iterator it; for(it=cars.begin();it!=cars.end();++it){ if(it->second==max_parking_time){ printf("%s ",it->first.c_str()); } } printf("%02d:%02d:%02d",max_parking_time/3600,max_parking_time%3600/60,max_parking_time%60); return 0; }