P1897 电梯里的爱情 [洛谷]

1.题目

题目描述

细心的同事发现,小 W 最近喜欢乘电梯上上下下,究其原因,也许只有小W自己知道:在电梯里经常可以遇到他心中的女神 PR。

电梯其实是个很暧昧的地方,只有在电梯里,小 W 才有勇气如此近距离接近女神,虽然觉得有点不自在,但次数多了,女神也习惯了小 W 的存在,甚至熟悉到仿佛不说上句话自己也都觉得不合适了。可是,他们的谈话也仅仅限于今天天气不错啊或是你吃了吗之类的,往往在对方微笑点头后就再次陷入难堪的沉默之中。 于是,小 W 便在陪伴女神的同时,也关注着电梯中显示的楼层数字,并且他注意到电梯每向上运行一层需要 6 6 6 秒钟,向下运行一层需要 4 4 4 秒钟,每开门一次需要 5 5 5 秒(如果有人到达才开门),并且每下一个人需要加 1 1 1 秒。

特别指出,电梯最开始在 0 0 0 层,并且最后必须再回到 0 0 0 层才算一趟任务结束。假设在开始的时候已知电梯内的每个人要去的楼层,你能计算出完成本趟任务需要的总时间吗?

这是个很简单的问题,要知道,小 W 已经修炼到快速心算出结果的境界,现在你来编程试试吧!

输入格式

2 2 2
1 1 1 行,一个正整数 n n n,表示乘坐电梯的人数。
2 2 2 行, n n n 个正整数, a i a_{i} ai 表示第 i i i 个人要去的楼层。

输出格式

1 1 1 行,一个正整数,表示完成这趟任务需要的时间。

样例输入 #1

4
2 4 3 2

样例输出 #1

59

提示

对于 60 % 60\% 60% 的数据 0 < n < 1 0 4 0<n<10^4 0<n<104

对于 100 % 100\% 100% 的数据 0 < n < 1 0 5 0<n<10^5 0<n<105 0 < a i ≤ 2 × 1 0 7 0<a_{i}\leq 2\times 10^7 0<ai2×107

2.分析

总时间= 电梯上下运行 + 开门时间 + 上下时间
电梯上下运行 = max(层数)❌10
开门时间 = 不同层数 ❌ 5
上下时间 = 人数

[set挺合适的~不过最开始没想到]

3.代码

1. 70分 TLE

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>  //find();
typedef vector <int> VI;
typedef long long LL;
int main()
{
	int n;
	scanf("%d", &n);
	VI difs;
	int maxn = 0;
	for (int i = 0; i < n; ++i)
	{
		int t;
		scanf("%d", &t);
		maxn = max(maxn, t);
		auto res = find(difs.begin(), difs.end(), t);
		if (res == difs.end()) difs.push_back(t);
	}
	LL res = 10 * maxn + 5 * difs.size() + n;
	printf("%lld", res);
	return 0;
}

原因分析:
find函数,较为缓慢

2. AC vector、erase、sort、unique

前置知识:
erase()、unique()函数

#include <iostream>
using namespace std;
#include <algorithm>  //sort
#include <vector>   //vector
typedef long long LL;
typedef vector <int> VI;
//res只与maxn与difs.size()有关,则直接排序去重即可
int main()
{
	int n;
	scanf("%d", &n);
	VI difs;  //存储 不同的楼层个数
	int maxn = 0;
	for (int i = 0; i < n; i++)
	{
		int t;
		scanf("%d", &t);
		maxn = max(maxn, t);
		difs.push_back(t);
	}
	sort(difs.begin(), difs.end());   //排序
	difs.erase(unique(difs.begin(), difs.end()), difs.end());  //去重
	LL res = 10 * maxn + 5 * difs.size() + n;
	printf("%lld", res);
	return  0;
}

3.priority_quque 优先队列 [方便获取最大值]

速度慢了很多,内存占用也挺多

#include <iostream>
using namespace std;
#include <queue>  //priority_queue
#include <algorithm>  //sort;
typedef priority_queue <int> PQI;
typedef long long LL;
PQI fls;  //优先队列,默认大根堆,即最大值即为顶

inline int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	while (!isdigit(ch))
	{
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch))
	{
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}

int ttime(int x)
{
	int t = 5;
	while (fls.top() == x && fls.size()) t++, fls.pop();
	return t;
}

int main()
{
	int n;
	scanf("%d", &n);
	//读入所有楼层
	for (int i = 0; i < n; ++i) fls.push(read());
	//上下楼运行时间
	LL res = 10 * fls.top();
	//开门+出门
	while (fls.size()) res += ttime(fls.top());
	printf("%lld", res);
	return 0;
}

注:该方法调用时,在VS中会报 front called on empty vector 错误,具体原因是调用top()时,会调用front(),为空时,不可调用front()

4.set 集合

#include <iostream>
using namespace std;
#include <set>
set<int> fls;
int main()
{
	int n;
	scanf("%d", &n);
	for(int i=0;i<n;++i)
	{
		int x;
		scanf("%d", &x);
		fls.insert(x);
	}
	//int maxn = *fls.rbegin();
	//或者 
	int maxn = *(--fls.end());
	int res = 10 * maxn + 5 * fls.size() + n; //最多1e7
	printf("%d", res);
	return 0;
}

注:set会自动排序、自动去重,同时注意如何取得set最后一个元素

4.总结

灵活运用 优先队列、set

5.更新日志

2022.8.6

欢迎交流、讨论、指正~
不正确、不理解之处欢迎评论留言~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值