1 条题解
-
0
📝 题目大意
有一个包含 首歌的循环播放列表,每首歌有其固定的时长 秒。给定一个时间点 (保证不会恰好落在歌曲切换的瞬间),求此时正在播放哪首歌,以及这首歌已经播放了多少秒。
💡 解题思路
-
题目分析:播放列表是周期循环的,总周期为 。由于 ,,,需要开
long long,且不能直接模拟 秒的播放过程。 -
算法推导:
- 先算出所有歌曲的总时长 。
- 将 对 取模:。这一步将 映射到第一个播放周期内,因为每经过一个完整周期,播放状态会回到起点。
- 遍历歌曲 :
- 若 ,说明当前时间点落在这首歌的播放过程中,输出歌曲编号 和已播放时间 。
- 否则,,表示这首歌已经完整播完,跳过它继续检查下一首。
-
边界与细节:
- 题目保证 不会恰好落在歌曲切换时刻,因此不会出现 或 (取模后)的边界情况,代码中直接用
<判断即可。 - 当 很大时( 级别), 可能达到 ,需要使用
long long(C++ 中int64_t或#define int long long)。 - 取模操作 保证了后续遍历时 ,因此一定能在 首歌中找到答案,不会出现遍历完未输出的情况。
- 题目保证 不会恰好落在歌曲切换时刻,因此不会出现 或 (取模后)的边界情况,代码中直接用
⏱️ 复杂度分析
- 时间复杂度:,一次求和与一次遍历。
- 空间复杂度:,用于存储 首歌的时长数组。
💻 标准代码 (C++)
#include<bits/stdc++.h> using namespace std; #define int long long // 数据范围较大,统一使用 long long const int N=1e5+10; int s,a[N]; // s: 所有歌曲总时长, a[i]: 第 i 首歌的时长 signed main() { int n,t;scanf("%lld%lld",&n,&t); for(int i=1;i<=n;i++)scanf("%lld",&a[i]),s+=a[i]; // 读入每首歌并累加总时长 t=t%s; // 取模,将 T 映射到第一个播放周期内 for(int i=1;i<=n;i++) { if(t<a[i]) // 当前时间落在第 i 首歌的播放过程中 { printf("%lld %lld\n",i,t); // 输出歌曲编号和已播放秒数 return 0; } else t-=a[i]; // 跳过这首歌,减去其时长 } return 0; } -
- 1
信息
- ID
- 659
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 3
- 已通过
- 3
- 上传者