牛客编程题:游船出租

题目描述:
现有公园游船租赁处请你编写一个租船管理系统。当游客租船时,管理员输入船号并按下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
如果代码有错误或者有更好的算法,欢迎指正、指导。
小男子不才,前排大佬让一让!抱拳!抱拳!

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/85236712