牛客题解 Channels
链接:https://ac.nowcoder.com/acm/problem/201606
来源:牛客网
题解
作者 岛田小雅
要求一段区间内的有效时间总和,第一反应用前缀和。要求 \(l\) 和 \(r\) 之间有效时间的和,就用 \(r\) 的有效时间减去 \(l\) 的有效时间。
有效时间的计算方法:
令时刻 \(i\) 之前的有效时间为 \(s_{i}\)。整段的节目一共有 \(\frac{i}{60}\times{50}\) 分钟,剩下的看了一半的是 \(i\bmod{60}\) 分钟。\(s_{i}=\frac{i}{60}\times{50}+i\bmod{60}\)。
这样的话我们的答案就是 \(s_{r}-s_{l-1}=\frac{r}{60}\times{50}+r\bmod{60}-(\frac{l-1}{60}\times{50}+(l-1)\bmod{60})\)。
但是这样提交一发的话我们会发现连样例都过不了。问题出在示例 \(2\) 的第 \(5\) 个测试点。把 \(\frac{r}{60}\times{50}\),\(r\bmod{60}\),\(\frac{l-1}{60}\times{50}\),\((l-1)\bmod{60}\) 分别输出出来后会发现,在计算不满 \(60\) 分钟的时间时,如果它超过 \(50\) 分钟但小于 \(60\) 分钟,那么程序会把超过 \(50\) 分钟的部分,也就是休息时间,也算进有效时间里。
解决方法很简单,使用 \(\min()\) 函数让计算进答案的剩余时间不超过 \(50\) 就可以了。
AC 代码
作者 岛田小雅
#include <bits/stdc++.h>
using namespace std;
long long l, r;
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
while(cin >> l >> r)
{
l--; // 提前把l减掉1来计算
cout << r/60*50+min(50ll,r%60)-(l/60*50+min(50ll,l%60)) << '\n';
}
return 0;
}