codeforces刷题(1100):1902B_div2

发布时间 2023-12-28 16:20:11作者: Tom-catlll

B、Getting Points

跳转原题点击此:该题地址

1、题目大意

  Monocarp为了完成总共n天的某学期的p学分任务。Monocarp每天可以选择两种度过方式:上一次课和完成最多两个任务 或者 休息一天。其中上课获得l学分,每个任务获得t学分,其中任务不可以重复接取,并且每周获得一个新的任务(第一天获得第一个任务,第8天获得第二个任务,以此类推),每个任务接取后可以在任意一天完成。
  Monocarp只想完成最低要求并获得最大休息天数,问如何安排学习任务可以获得最大休息天数。

2、题目解析

  由于每个任务接取后可以在任意一天完成,所以我们可以倒着往前推,先按照每天上一次课和两个任务(如果有的话)算,如果学分还不够就不断地每天上课直至完成即可。

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 2e5+10;

int T;
ll n, p, l, t;  // 注意输入范围
int f[N];

void solve()
{
	cin >> n >> p >> l >> t;
	
	ll tasks = 0;   // 计算该学期一共能有几个任务
	if(n % 7 == 0)
		tasks = n / 7;
	else
		tasks = n / 7 + 1;
		
	ll tmp = tasks / 2;	
    //计算有多少个既能上课又能完成两个任务的天数
	ll sum_day = tmp * t * 2 + l * tmp;
	if(sum_day >= p)	// 如果满学习的天数 >= 总学分
	{
		ll tmp1 = 2 * t + l;
		if(p % tmp1 == 0)	// 算只需要几个满任务天数
			cout << n - (p / tmp1) << endl;
		else
			cout << n - (p / tmp1 + 1) << endl;
		return;
	}
	p -= sum_day;	// 满学习的总学分不足则用上课和多余的任务补足
	
	if(tasks % 2 == 1)	// 如果总任务是奇数,则最开始会有一个不算在那
	{
		if(p <= (l + t))
		{
			cout << n - (tmp + 1) << endl;
			return;
		}
		p -= (l + t);  // 剩余要求学分
		tmp++;
	}
    // 如果任务都解决了学分还是不够,那就只能上课
	if(p % l == 0)
		cout << n - (tmp + p / l) << endl;
	else
		cout << n - (tmp + p / l + 1) << endl;
}

int main()
{
	cin >> T;
	while (T--)
	{
		solve();
	}

	return 0;
}