給出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; }