- 公交换乘 (Bus Transfer)
怎么优化时间复杂度
- @ 2026-3-24 17:44:53
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,pay=0;
cin >> n;
bool way[n];
int price[n],t[n],yhj=0,yhjt[n],yhjzz[n],last=0;
for(int i=0;i<n;i++)
{
cin >> way[i]>>price[i]>>t[i];
int deltat=t[i]-last;
for(int j=1;j<=yhj;j++)
{
yhjt[j]-=deltat;
}
if(way[i]==0)
{
yhj++;
pay+=price[i];
yhjt[yhj]=45;
yhjzz[yhj]=i;
}
else if(way[i]==1)
{
pay+=price[i];
for(int j=1;j<=yhj;j++)
{
if(yhjt[j]>=0&&price[yhjzz[j]]>=price[i])
{
yhjt[j]=-1;
pay-=price[i];
// cout<<yhjt[2]<<" ";
break;
}
}
}
// cout <<pay<<"\n";
last=t[i];
}
cout << pay;
}
1 comments
-
Myobot @ 2026-3-24 17:45:24
同学你好,我看了你的代码。你的思路是模拟优惠票的过期和使用过程,但时间复杂度确实存在问题。
当前代码的问题分析
-
时间复杂度:你的代码中,每次处理一条记录时,都会遍历所有优惠票(
for(int j=1;j<=yhj;j++)),这会导致最坏情况下 的时间复杂度。当 时,这显然会超时。 -
过期处理方式:你通过
yhjt[j]-=deltat来更新所有优惠票的剩余时间,但这样每次都要更新所有票,效率很低。
优化思路
关键观察
- 时间顺序:题目保证记录按时间顺序给出,且时间单调递增。
- 优惠票的有效性:一张优惠票在时间 有效,当且仅当 。
- 使用规则:优先使用获得最早的优惠票。
优化方向
-
避免遍历所有票:
- 优惠票的有效期是固定的45分钟,不是动态递减的。
- 对于当前时间 ,一张票 有效当且仅当 。
- 因此,我们可以维护一个队列,队列中的票按获得时间排序。
-
过期票的移除:
- 在处理每条记录时,可以先将所有过期的票从队列中移除。
- 由于时间单调递增,过期票只会出现在队列头部。
-
查找可用票:
- 需要找到队列中第一张票价不低于公交车票价的票。
- 如果直接遍历队列,最坏情况还是 。
- 需要更高效的数据结构或策略。
思考题引导
-
数据结构选择:
- 你需要一个能快速移除过期票的数据结构(队列适合)。
- 你需要一个能快速找到票价不低于某个值的票的数据结构。
- 这两者可能有冲突,如何协调?
-
复杂度目标:
- 数据范围 ,需要 或 的算法。
- 每次操作(添加票、查找可用票、移除过期票)应该尽量在 或 内完成。
-
具体策略:
- 考虑维护两个数据结构: a. 一个队列,按时间顺序存储所有未使用的优惠票。 b. 一个能快速查询票价不低于某个值的数据结构。
- 票价范围只有 ,这个范围很小,能否利用这个特点?
下一步建议
-
重新设计数据结构:
- 考虑使用
deque或普通队列来按时间顺序存储优惠票。 - 考虑票价范围很小(1-1000),可以使用桶或类似结构来加速查找��
- 考虑使用
-
算法流程:
- 处理地铁记录:将票加入队列和相应的数据结构。
- 处理公交记录: a. 移除所有过期票(从队列头部开始检查)。 b. 查找票价不低于公交车票价的票。 c. 如果找到,使用最早的那张(注意规则)。
-
实现细节:
- 如何保证找到的是"最早获得的"优惠票?
- 如何高效移除过期票?
你可以先思考一下这些方向,然后尝试重新设计算法。如果需要进一步的提示,可以告诉我你现在的思路。
-
- 1
Information
- ID
- 666
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 6
- Tags
- # Submissions
- 65
- Accepted
- 19
- Uploaded By