牛客程式設計題:遊船出租
題目描述:
現有公園遊船租賃處請你編寫一個租船管理系統。當遊客租船時,管理員輸入船號並按下S鍵,系統開始計時;當遊客還船時,管理員輸入船號並按下E鍵,系統結束計時。船號為不超過100的正整數。當管理員將0作為船號輸入時,表示一天租船工作結束,系統應輸出當天的遊客租船次數和平均租船時間。 注意:由於線路偶爾會有故障,可能出現不完整的紀錄,即只有租船沒有還船,或者只有還船沒有租船的紀錄,系統應能自動忽略這種無效紀錄。
輸入描述:
測試輸入包含若干測試用例,每個測試用例為一整天的租船紀錄,格式為:
船號(1~100) 鍵值(S或E) 發生時間(小時:分鐘)
每一天的紀錄保證按時間遞增的順序給出。當讀到船號為-1時,全部輸入結束,相應的結果不要輸出。
輸出描述:
對每個測試用例輸出1行,即當天的遊客租船次數和平均租船時間(以分鐘為單位的精確到個位的整數時間)。
示例1
輸入
1 S 08:10
2 S 08:35
1 E 10:00
2 E 13:16
0 S 17:00
0 S 17:00
3 E 08:10
1 S 08:20
2 S 09:00
1 E 09:20
0 E 17:00
-1
輸出
2 196
0 0
1 60
演算法思路:利用map容器進行標記每一次借船的時間,然後對還船操作進行有效性判斷、時間計算。(正常的邏輯應該是一條船借出然後還船,然後再解除、還船,這應該算為兩次。但牛客上的測試用例邏輯為,第二次使用沒有借船過程,直接還船,借船的時間仍然為第一次借船的時間。)
#include<iostream> #include<string> #include<map> #include<cmath> using namespace std; //用於求借船時間和還船時間中間的分鐘數 int runTime(string &strBegin, string &strEnd) { int beginHours = (strBegin[0] - '0') * 10 + (strBegin[1] - '0'); int beginMins = (strBegin[3] - '0') * 10 + (strBegin[4] - '0'); int endHours = (strEnd[0] - '0') * 10 + (strEnd[1] - '0'); int endMins = (strEnd[3] - '0') * 10 + (strEnd[4] - '0'); return endHours * 60 + endMins - beginHours * 60 - beginMins; } int main() { map<int, string> shipMap;//用於記錄借船記錄 int validCnt = 0;//有效的記錄(包含借船和換船兩個部分) int sumTime = 0;//有效運營時間 int shipNum;//輸入的船號 char opeartion;//輸入的操作,'S'代表借船, 'E'代表還船 char inputTimeStr[10];//輸入的字串 while (cin >> shipNum) { if (shipNum == -1) { //如果輸入的-1,則直接退出 break; } scanf(" %c %s", &opeartion, inputTimeStr); string timeStr = string(inputTimeStr);//將char*轉換成string型 if (shipNum == 0) { //如果輸入的頭字元為0 //輸出有效次數,平局借船時間(按題目要求,精確到個位) if (validCnt == 0) { //如果是0次則直接輸出,放置除數為零 cout << "0 0" << endl; } else { //這裡使用到數學中的"四捨五入"除法 cout << validCnt << " " << round(sumTime * 1.0 / validCnt) << endl; } shipMap.clear();//清空記錄容器 validCnt = sumTime = 0;//清空上一次的記錄時間 } else { if (opeartion == 'S') { //如果是借船 shipMap[shipNum] = timeStr; } else { //如果是還船 if (shipMap.count(shipNum) == 1) { //如果這條船有借船記錄 //加上該船的執行時間 sumTime += runTime(shipMap[shipNum], timeStr); //有效次數增加 ++validCnt; //此處如果是正常的邏輯,應該將上一次借船的時間移除,下一次還船前必須有借船的操作 ////將該船的借船記錄移除 //shipMap.erase(shipNum); } } } } return 0; }
那個不正常的邏輯真是快搞死我了,在八十多行的測試用例中進行單步執行,都是淚啊。。。
執行時間:6ms
佔用記憶體:504k
如果程式碼有錯誤或者有更好的演算法,歡迎指正、指導。
小男子不才,前排大佬讓一讓!抱拳!抱拳!