A1095 Cars on Campus (30)(30 分)
A1095 Cars on Campus (30)(30 分)
Zhejiang University has 6 campuses and a lot of gates. From each gate we can collect the in/out times and the plate numbers of the cars crossing the gate. Now with all the information available, you are supposed to tell, at any specific time point, the number of cars parking on campus, and at the end of the day find the cars that have parked for the longest time period.
Input Specification:
Each input file contains one test case. Each case starts with two positive integers N (<= 10000), the number of records, and K (<= 80000) the number of queries. Then N lines follow, each gives a record in the format
plate_number hh:mm:ss status
where plate_number is a string of 7 English capital letters or 1-digit numbers; hh:mm:ss
Note that all times will be within a single day. Each "in" record is paired with the chronologically next record for the same car provided it is an "out" record. Any "in" records that are not paired with an "out" record are ignored, as are "out" records not paired with an "in" record. It is guaranteed that at least one car is well paired in the input, and no car is both "in" and "out" at the same moment. Times are recorded using a 24-hour clock.
Then K lines of queries follow, each gives a time point in the format hh:mm:ss. Note: the queries are given in ascending order of the times.
Output Specification:
For each query, output in a line the total number of cars parking on campus. The last line of output is supposed to give the plate number of the car that has parked for the longest time period, and the corresponding time length. If such a car is not unique, then output all of their plate numbers in a line in alphabetical order, separated by a space.
Sample Input:
16 7
JH007BD 18:00:01 in
ZD00001 11:30:08 out
DB8888A 13:00:00 out
ZA3Q625 23:59:50 out
ZA133CH 10:23:00 in
ZD00001 04:09:59 in
JH007BD 05:09:59 in
ZA3Q625 11:42:01 out
JH007BD 05:10:33 in
ZA3Q625 06:30:50 in
JH007BD 12:23:42 out
ZA3Q625 23:55:00 in
JH007BD 12:24:23 out
ZA133CH 17:11:22 out
JH007BD 18:07:01 out
DB8888A 06:30:50 in
05:10:00
06:30:50
11:00:00
12:23:42
14:00:00
18:00:00
23:59:00
Sample Output:
1
4
5
2
1
0
1
JH007BD ZD00001 07:20:09
思考
《算法筆記》胡凡6.4節
map的常見用法
8月18日,還是買了紙質版,作為一份積累代碼的紙質資料,還是很有用的,可以做到快速地代碼復用。
c語言的string與c++的string
例(1)
函數聲明:const char *c_str();
c_str()
函數返回一個指向正規C字符串的指針, 內容與本string
串相同.
這是為了與c語言兼容,在c語言中沒有string類型,故必須通過string
類對象的成員函數c_str()
把string
對象轉換成c中的字符串樣式。
註意:一定要使用strcpy()
函數 等來操作方法c_str()
返回的指針
比如:最好不要這樣:
char* c;
string s="1234";
c = s.c_str();
//c最後指向的內容是垃圾,因為s對象被析構,其內容被處理(糾正:s對象的析構是在對指針c完成賦值操作之後進行的,故此處並沒有錯誤)
在vc++2010中提示的錯誤原因:
vc++2010中提示的錯誤原因
char c[20];
string s="1234";
strcpy(c,s.c_str());
這樣才不會出錯,c_str()
返回的是一個臨時指針,不能對其進行操作
c_str()
返回的是一個分配給const char
的地址,其內容已設定為不可變更,如果再把此地址賦給一個可以變更內容的char變量,就會產生沖突,在2010中是不被允許的。但是如果放入函數調用,或者直接輸出,因為這些函數和輸出都是把字符串指針作為 const char*
引用的,所以不會有問題。
例(2)
c_str()
以const char*
類型返回 string
內含的字符串
如果一個函數要求char*
參數,可以使用c_str()
方法:
string s = "Hello World!";
printf("%s", s.c_str()); //輸出 "Hello World!"
c_str
在打開文件時的用處:
當需要打開一個由用戶自己輸入文件名的文件時,可以這樣寫:ifstream in(st.c_str());
。其中st是string類型,存放的即為用戶輸入的文件名。
AC代碼
/*由於要使用map,故在本體只有用c++來處理問題,map<string,int>
因此需要cstring string map,那麽也使用<algorithm>的sort好了*/
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
const int maxn = 10010; //記錄數N<=10000
struct Car{
char id[8];//7個英文大寫字母,1位數字
int time;//將時間單位轉化為s,這與前面的A1016計算話費的代碼實現不同,那個用了while循環
char status[4];//in或者是out
}all[maxn],valid[maxn];//all為所有記錄,valid為有效記錄
int num = 0;//有效記錄的條數
map<string, int> parkTime;//車牌號->總停留時間 ,這裏的string要是c++的string類型才行
//timeToInt將時間轉換為以s為單位,簡化時間排序代碼
int timeToInt(int hh, int mm, int ss){
return hh*3600 + mm * 60 + ss;
}
//將車牌號按字典序從小到大排序,若車牌號相同,則按時間從小到大排序
bool cmpByIdAndTime(Car a,Car b){
if(strcmp(a.id,b.id))
return strcmp(a.id,b.id) < 0;/*id升序*/
else return a.time < b.time;/*時間值升序*/
}
//按時間從小到大排序
bool cmpByTime(Car a, Car b){
return a.time < b.time;
}
int main(){
int n, k, hh, mm , ss;
scanf("%d%d", &n, &k);//記錄數,查詢數
for(int i=0;i<n;i++){
scanf("%s %d:%d:%d %s", all[i].id, &hh, &mm, &ss, all[i].status);
all[i].time = timeToInt(hh,mm,ss);//轉換為以s為單位,簡化了時間存儲和比較的代碼
}
sort(all,all+n,cmpByIdAndTime);//排序
int maxTime =-1;//最長總停留時間,哨兵
for(int i=0;i<n-1;i++){//遍歷所有記錄
if(!strcmp(all[i].id,all[i+1].id) && //i和i+1同一車牌號
!strcmp(all[i].status,"in") && //i是in記錄
!strcmp(all[i+1].status,"out") ){//i+1是out記錄
valid[num++]=all[i];//i和i+1配對,存入valid數組
valid[num++]=all[i+1];
int inTime = all[i+1].time - all[i].time; //此次停留時間
if(parkTime.count(all[i].id) == 0) {//count()的用法:返回關鍵字為all[i].id的數量,即車牌號為all[i].id的數量
parkTime[all[i].id]=0;//map中沒有這個車牌號,置零 ,其實是節約成本的初始化
}
parkTime[all[i].id]+=inTime;//增加該車牌號的總停留時間
maxTime=max(maxTime,parkTime[all[i].id]);//更新最大總停留時間
}
}
sort(valid,valid+num,cmpByTime);//有效記錄時間升序
//now指向不超過當前查詢時間的記錄,numCar為當前校園內車輛數
int now=0,numCar=0;
for(int i=0;i<k;i++){
scanf("%d:%d:%d",&hh,&mm,&ss);
int time =timeToInt(hh,mm,ss);
//讓now處理至當前查詢時間
while(now<num && valid[now].time<=time){//防止數組越界
if(!strcmp(valid[now].status,"in"))
numCar++;//車輛進入
else numCar--;//車輛離開
now++;//指向下一條記錄
}
printf("%d\n",numCar);//輸出該時刻校園內車輛數
}
map<string,int>::iterator it;//遍歷所有車牌號
for(it=parkTime.begin();it != parkTime.end();it++){
if(it->second==maxTime){//輸出所有最長總停留時間的車牌號
printf("%s ",it->first.c_str()); //c++字符串轉為c語言字符串操作
}
}
printf("%02d:%02d:%02d\n",maxTime/3600,maxTime%3600/60,maxTime%60);
return 0;
}
A1095 Cars on Campus (30)(30 分)