首页 > 其他分享 >Educational Codeforces Round 159 (Rated for Div. 2)

Educational Codeforces Round 159 (Rated for Div. 2)

时间:2023-12-04 17:12:16浏览次数:30  
标签:std Educational Rated ok 159 sum break dy ll

Educational Codeforces Round 159 (Rated for Div. 2)

基本情况

A题秒了。

B题想出来贪心思想,也想出来怎么找最优解了,但实现极其复杂繁琐,最后以先超时优化后又错误的结果告终。

B. Getting Points

明显越后面开始学收益越高。

然后写了个简单粗暴的纯模拟,T了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using ll = long long;

int T;
ll n, l, t, p;

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	std::cin >> T;
	while (T--)
	{
		ll sum = 0, cnt = 0;
		std::cin >> n >> p >> l >> t;
		ll tn = n;
		ll task = n / 7;
		if (n % 7 != 0)
			task = task + 1;
		while (n)
		{
			bool ok = false;
			int dy = (n % 7) ? (n % 7) : 7;
			int wk = n / 7;
			n -= dy;
			if (dy)
				wk = wk + 1;
			if (wk < 2)
			{
				for (int i = 1; i <= dy; i++)
				{
					if (task == 0)
					{
						sum += (dy - i + 1) * l;
						cnt += dy - i + 1;
						if (sum >= p)
						{
							while (sum - l >= p)
							{
								cnt--;
								sum -= l;
							}
							ok = true;
						}
						break;
					}
					sum += t + l;
					cnt++;
					if (sum >= p)
					{
						ok = true;
						break;
					}
					task--;
				}
				continue;
			}
			for (int i = 1; i <= dy; i++)
			{
				if (task >= 2)
				{
					sum += 2 * t + l;
					cnt++;
					if (sum >= p)
					{
						ok = true;
						break;
					}
					task -= 2;
				}
				else if (task >= 1)
				{
					sum += t + l;
					cnt++;
					if (sum >= p)
					{
						ok = true;
						break;
					}
					task -= 1;
				}
				else
				{
					sum += l * (dy - i + 1);
					cnt += dy - i + 1;
					if (sum >= p)
					{
						while (sum - l >= p)
						{
							cnt--;
							sum -= l;
						}
						ok = true;
					}
					break;
				}
			}
			if (ok)
			{
				break;
			}
		}
		std::cout << tn - cnt << std::endl;
	}
	return 0;
}

然后就想着去掉循环的部分,全部用式子直接算,但是太多要处理的细节了,码力拉了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using ll = long long;

int T;
ll n, l, t, p;

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	std::cin >> T;
	while (T--)
	{
		std::cin >> n >> p >> l >> t;
		ll sum = 0, ans = 0;
		ll tDay = n;
		ll task = (n % 7 == 0) ? n / 7 : n / 7 + 1;
		int dy, wk;
		while (tDay != 0)
		{
			bool ok = false;
			if (tDay % 7 == 0)
			{
				dy = 7, wk = tDay / 7 + 1;
			}
			else
			{
				dy = tDay % 7, wk = tDay / 7;
			}
			tDay -= dy;
			if (wk == 1)
			{
				sum += t + dy * l;
				ans += dy;
				if (sum > p)
				{
					ans -= (sum - t - p) / l;
					sum -= sum - t - p;
					if (sum > p)
					{
						ans -= 1;
					}
				}
				continue;
			}
			if (task <= dy * 2)
			{
				int task_day = task / 2;
				if (task % 2 != 0)
					task_day++;
				int ntd = dy - task_day;
				sum += task * t + dy * l;
				ans += dy;
				if (sum >= p)
				{
					ok = true;
					if (sum > p)
					{
						if (sum - ntd * l <= p)
						{
							ans -= (sum - p) / l;
						}
						else
						{
							ans -= ntd;
							if (task % 2 == 0)
								ans -= (sum - p) / (l + t * 2);
							else
							{
								sum -= (t + l);
								ans -= 1;
								if (sum > p)
								{
									ans -= (sum - p) / (l + t * 2);
								}
							}
						}
					}
					break;
				}
				break;
			}
			else
			{
				task -= dy * 2;
				sum += dy * (l + t * 2);
				//printf("ans = %d, dy = %d\n", ans, dy);
				ans += dy;
				if (sum >= p)
				{
					ok = true;
					if (sum > p)
					{
						ans -= (sum - p) / (l + t * 2);
					}
					break;
				}
			}
			if (ok)
				break;
		}
		std::cout << n - ans << std::endl;
	}
	return 0;
}

看了某佬的讲解,这题用二分答案简直轻松。

说白了,找最多休息天数,也就是找最少工作天数。

刚好符合二分答案最小的最大原则。(我居然没想到!)

直接二分最小天数 \(x\),校验即可。

校验函数也很有说法:

bool check(ll x)
{
	ll s = x * a + min(2 * x, (n + 6) / 7) * b;
	return s >= p;
}

思路是直接课程的学分 \(x\times a\) 再加上作业的学分 \(\min((n+6)/7,2\times x)\times b\) 即可(如果作业数够就是 \(2\times x\),不然就是 \((n + 6)/7\),即总周数,即刷出的总作业数。

我一开始觉得不严谨,万一周数为 1 要怎么特判呢,还有就是怎么保证这些作业都能做完呢。

后面仔细想想,每周才刷一个作业出来,作业量是远远小于天数的,是肯定可以保证写完的。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MP make_pair

ll n, p, a, b;

bool check(ll x)
{
	ll temp = x * a + min(x * 2, (n + 6) / 7) * b;
	return temp >= p;
}

void solve()
{
	cin >> n >> p >> a >> b;
	ll l = 1, r = n, mid;
	while (l <= r)
	{
		mid = l + r >> 1;
		if (check(mid))
		{
			r = mid - 1;
		}
		else
		{
			l = mid + 1;
		}
	}
	cout << n - l << endl;
}

int main()
{
	ios::sync_with_stdio(false);
	int _;
	cin >> _;
	while (_--)
		solve();
}

标签:std,Educational,Rated,ok,159,sum,break,dy,ll
From: https://www.cnblogs.com/kdlyh/p/17875423.html

相关文章

  • 13、深度学习入门:P154、P155、P156、P157、P158、P159
    1、调整权重和偏置以便拟合训练数据的过程称为学习这句话指的是机器学习中模型训练的过程。在训练一个机器学习模型时,我们通常有一个训练数据集,其中包含输入和对应的期望输出。模型的目标是通过学习这些数据中的模式和规律,以便在未见过的数据上做出准确的预测或执行任务。模型学......
  • [Codeforces] CF1591C Minimize Distance
    CF1591CMinimizeDistance题目一条线上有\(n\)(\(1\len\le2\cdot10^5\))个仓库,第\(i\)个仓库的位置是\(x_i\)(\(1\lei\len\))。你有\(n\)箱货物,要分别运到这\(n\)个仓库里。你的初始位置在点\(0\),一次可以携带\(k\)(\(1\lek\len\))箱货物。在送完携带......
  • Educational Codeforces Round 158 (Rated for Div. 2)
    A.LineTripThereisaroad,whichcanberepresentedasanumberline.Youarelocatedinthepoint\(0\)ofthenumberline,andyouwanttotravelfromthepoint\(0\)tothepoint\(x\),andbacktothepoint\(0\).Youtravelbycar,whichs......
  • CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
    看到B官方题解写了一堆,而如果能注意到一些性质,几行就写完了题意:给一个A,B构成的字符串,可以将“AB”翻转成"BA",问最多可以进行多少次翻转?实际上在手动模拟以后发现,由于题目限制了每个位置只能翻转一次,所以情况简单了不少。只要还没过最后一个B,那么最后一个B之前的所有A就会被反......
  • CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
    CodeTONRound7(Div.1+Div.2,Rated,Prizes!)A-JaggedSwaps思路:a2到an的数只要相邻为逆序都可以交换,只需要判断a1是否为1即可#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong//#defineint__int128#definedoublelongdoubletypedefpai......
  • CF1599H Hidden Fortress
    看到很多是用二分的解法,这题其实可以这用**$4$**次查询得到结果。我们只需要用两次查询就可以找到地方基地矩阵的一条边的中点。先询问$d1=query(1,1)$和$d2=query(1,10^9)$。就可以求出$y_m=\frac{1+10^9+d1-d2}{2}$。之后再询问$d3=query(10^9,1)$和$d4=query(1,y_......
  • CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
    20231127A.JaggedSwaps题意是:给你一个数组进行无数次的操作问你能不能单调思路:通过观察发现进行操作大的一定会被放在后面,所以一定会单调,但是操作是从2开始的,所以下表1的地方一定要是1usingnamespacestd;inta[20];voidsolve(){intn;cin>>n;for(in......
  • CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
    CodeTONRound7(Div.1+Div.2,Rated,Prizes!)A-JaggedSwaps解题思路:若\(a[1]=1\),则可以。代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;typedefpair<int,int>pii;#definefifirst#definesesecondvoidsolve(){......
  • CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
    CodeTONRound7(Div.1+Div.2,Rated,Prizes!)A-JaggedSwapsintmain(){IOS;for(cin>>_;_;--_){cin>>n;rep(i,1,n)cin>>a[i];while(true){boolf=0;rep(i,......
  • CF 158 (Rated for Div
    CF-158这次比赛较上次也是有进步,成功地多AC了一道题。但第4题也是很遗憾只差一点了。A.LineTrip题意:车在数轴上从$0$点到达$x$点又返回$0$点,有$k$点的油,可以走$k$个单位,在数轴上$a_1,a_2,a_3...a_n$处可以加油到$k$点,$0$点处和$x$点处无法加油,问$k$的最小值。思路:那么根据题......