题意
每学期为 $n$ 天,莫诺卡普必须在这 $n$ 天内获得至少 $P$ 分。获得分数有两种途径——完成实践任务或上课。每完成一项实践任务,蒙诺卡普就能获得 $t$ 分;每上一堂课,他就能获得 $l$ 分。
实践任务每七天解锁一个:第一个任务在第 $1$ 天解锁(可以在 $1$ 到 $n$ 的任何一天完成),第二个任务在 $8$ 天解锁(可以在 $8$ 到 $n$ 的任何一天完成),第三个任务在 $15$ 天解锁,以此类推。
从 $1$ 到 $n$ ,每天都有一堂课可以让莫诺卡普参加。每天,莫诺卡普都可以选择是学习还是休息一整天。当蒙诺卡普决定学习时,他可以上一堂课,并完成不超过 $2$ 个解锁了但未完成的任务。如果莫诺卡普全天休息,他将跳过一堂课,并不做任何任务。
求莫诺卡可以休息的最大天数。
$1 \le n, l, t \le 10^9$ ;
$1 \le P \le 10^{18}$。
题解
要求休息的最大天数,等于求不休息的最小天数,显然不休息的天数越多,所获得的学分也越多,所以我们可以二分不休息的天数,设为 $m$。然后我们计算不休息 $m$ 天所能获得的最大学分。
学分由两部分组成——课程和实践任务,所以我们分开计算。课程所获得的学分为 $m \cdot l$。实践任务所获得的学分为 $(\left\lfloor \frac{n - 1}{7} \right\rfloor + 1) \cdot 2m$。
Code:
#include <iostream>
using namespace std;
typedef long long ll;
ll T, n, l, t, P;
ll sum (ll m) {
return m * l + min (m << 1, (n - 1) / 7 + 1) * t;
}
ll solve () {
ll L = 0, R = n, M;
while (L <= R) {
M = L + R >> 1;
if (sum (M) >= P) R = M - 1;
else L = M + 1;
}
return R + 1;
}
int main () {
ios::sync_with_stdio (false);
cin.tie (0);
cin >> T;
while (T--) {
cin >> n >> P >> l >> t;
cout << n - solve () << '\n';
}
return 0;
}