1. 程式人生 > >牛客程式設計題:遊船出租

牛客程式設計題:遊船出租

題目描述:
現有公園遊船租賃處請你編寫一個租船管理系統。當遊客租船時,管理員輸入船號並按下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
如果程式碼有錯誤或者有更好的演算法,歡迎指正、指導。
小男子不才,前排大佬讓一讓!抱拳!抱拳!