week-3 天梯赛刷题 L1-043 阅览室

1、题目

天梯图书阅览室请你编写一个简单的图书借阅统计程序。当读者借书时,管理员输入书号并按下S键,程序开始计时;当读者还书时,管理员输入书号并按下E键,程序结束计时。书号为不超过1000的正整数。当管理员将0作为书号输入时,表示一天工作结束,你的程序应输出当天的读者借书次数和平均阅读时间。

注意:由于线路偶尔会有故障,可能出现不完整的纪录,即只有S没有E,或者只有E没有S的纪录,系统应能自动忽略这种无效纪录。另外,题目保证书号是书的唯一标识,同一本书在任何时间区间内只可能被一位读者借阅。

输入格式:

输入在第一行给出一个正整数N(≤10),随后给出N天的纪录。每天的纪录由若干次借阅操作组成,每次操作占一行,格式为:

书号([1, 1000]内的整数) 键值SE) 发生时间hh:mm,其中hh是[0,23]内的整数,mm是[0, 59]内整数)

每一天的纪录保证按时间递增的顺序给出。

输出格式:

对每天的纪录,在一行中输出当天的读者借书次数和平均阅读时间(以分钟为单位的精确到个位的整数时间)。

输入样例:

3
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

输出样例:

2 196
0 0
1 60

2、思路

实不相瞒,一开始打算通过STL的队列来做,但是之后发现想麻烦了,还是使用哈希表来做吧!

如果来到工作台的书籍号在哈希表里有了,并且之前的动作是借书,现在的动作是还书,那么就把

ans++,并且用现在的时间减去之前的时间(这里的时间是都先转换为分钟),然后把这本书从哈希表中移出去,对于只有E而没有S的情况。

我的代码对时间的处理可能会比较复杂,并且调了很久也发现没有通过第二个测试点,是在又是审题的问题,如果对于这样的情况

1 S 08:00
1 S 08:10
1 E 09:00
0 S 17:00

 

根据题意,有效的应该是第二次借书,第一次的借书应该算是无效的,我又会想为啥不是第二次无效,但后来想明白了,因为这是一段连续的借还书呀,你机器不可能会在中途出故障吧!!!所以第二次应该算有效。也就是对于同样的书在第二次S出现之前都没有E的,我们就考虑第二次的S。虽然过了,但还是要写一下我的17分代码:

3、17分代码与20分代码

若要20分,就去掉下面的注释就好了。

这里引用了四舍五入,round函数,在cmath文件里

#include
#include
#include
#include
#include
using namespace std;
unordered_map mm;
int a[10001];
int ans,time1;
int main()
{
	int n;
	scanf("%d",&n);
	int t = 0;
	while(t>id>>op>>tt;
		int m = 0;
		for(int i = 0;tt[i]!=':';i++)
		{
			m*=10;
			m+=tt[i]-'0';
		}
		int j = 0,s=0;
		for(int i = tt.size()-1;tt[i]!=':';i--)
		{
			s += (tt[i]-'0')*pow(10,j);
			j++;
		}
		int result = m*60 + s;
		if(id==0)
		{
			t++;
			if(ans>0)
				{
					cout<

4、简洁版本的代码

对时间的处理是我复杂了(对不起

其实直接当整数输出,然后输出小时的时候输出冒号就行,然后再输出分钟

查阅资料发现,其实还可以用sscanf来读入

sscanf 是 C/C++ 语言中的一个标准库函数,用于从字符串中读取格式化的输入。它是 scanf 函数的一个变体,scanf 用于从标准输入(通常是键盘)读取格式化输入,而 sscanf 则是从给定的字符串中读取。

在C++中,tt.c_str()的使用是将std::string类型的变量tt转换为C风格的字符串(即以'\0'结尾的字符数组)。这是因为sscanf函数并不直接接受std::string对象作为输入,它需要一个指向常量字符的指针(const char*)作为输入。

使用方法如下:字符串若不是char* 类型也就是C风格,需要先转换

std::string tt = "12:30";
int hours, minutes;
sscanf(tt.c_str(), "%d:%d", &hours, &minutes);

 我们这里就直接输入吧,不使用sscanf了,只供当自己了解了解

#include 
#include 
#include 
using namespace std;

int main() {
    int n;
    cin >> n;

    for (int day = 0; day < n; day++) {
        unordered_map borrowTime;
        int count = 0, totalTime = 0;

        while (true) {
            int id, hh, mm;
            char op, colon;
            cin >> id >> op >> hh >> colon >> mm;
            if (id == 0) break;

            int timeInMinutes = hh * 60 + mm;

            if (op == 'S') {
                borrowTime[id] = timeInMinutes;
            } else if (op == 'E' && borrowTime.find(id) != borrowTime.end()) {
                totalTime += timeInMinutes - borrowTime[id];
                borrowTime.erase(id);
                count++;
            }
        }

        if (count > 0) {
            int avgTime = (int)round((double)totalTime / count);
            cout << count << " " << avgTime << endl;
        } else {
            cout << "0 0" << endl;
        }
    }

    return 0;
}

 

 

你可能感兴趣的:(week3-pta,算法,数据结构)