CF1735 A. Working Week

题目链接

https://codeforces.com/contest/1735/problem/A

题意简述

你的工作周由 \(n\) 天组成, \(n\) 天后又轮到第 \(1\) 天,并且他们其中包含 \(3\) 天休息日,其中第 \(n\) 天必须是休息日 , 现在需要你选择剩下两天休息日.
需要满足以下条件

  • 这两天必须分开,不能连着. 提示:这也就意味着你不能选第一天作为休息日,因为它和第 \(n\) 天连着!
  • 这几天休息日把工作日分割成一个个工作日的段,长度分别为 \(l_1 \ l_2\ l_3\)

请你调整休息日的安排,输出 \(min(\)\(|l_1-l_2|,|l_2-l_3|,|l_1-l_3|)\) 的最大值.

样例

点击查看样例

分析

题意即想让这三段连续工作日的时间的两两差值尽量的大,不妨让 \(l_1 \leq l_2 \leq l_3\) .
则有\(l_1\) 一定等于 \(1\) , 假设 \(l_1 > 1\),那么只要让 \(l_1\)\(1\) , 让 \(l_3\) 增大 \(1\) 结果就更优了(\(l_2-l_1\)不变, \(l_3-l_1\)\(l_3-l_2\) 变大).

这三段两两的差值应该尽量接近,否则:如果有两段的差值变得更大,那么一定有两端的差值变得更小.

首先,一轮工作日去掉休息日有 \(n-3\) 天,\(1+l_2+l_3 = n-3\),其次,让两段工作日的时长尽量接近.\(l_3-l_2=l_2-1\)
那么只需解如下方程组

\(\left\{\begin{matrix}l_3-l_2=l_2-1\\ 1+l_2+l_3 = n-3 \end{matrix}\right.\)

联立方程组解得
\(l_2 = {n-3\over 3}\)
又由①可知 \(l_3\ = 2\ l_2-1\) 故有\(l_3-l_2 = l_2-1\)
并且因为 \(l_1=1\),所以\(l_2-l_1 =l_2-1\)
那么如果 $ 3\ |\ n-3\ $,结果一定是 \({n-3\over 3} - 1\)
如果不整除,, \(l_2\)若上取整(多1),根据\(1+l_2+l_3 = n-3\) ,那 \(l_3\)就得下取整(小1),最终\(|l_3-l_2|\)小了\(2\),显然\(l_3-l_2\)是最小值
\(l_2\)若下取整,那么\(l_2\)小了\(1\),最小值应该是\(l_2-1\),比上面的更大.所以下取整更优.那最终答案仍是\({n-3\over 3} - 1\)

代码

点击查看代码(比赛时写的麻烦的代码)
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
int main()
{
	//freopen("uva.txt","r",stdin);
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		if((n-4)%3==0)
		{
			printf("%d\n",(n-4)/3-1);
		}
		else
		{
			printf("%d\n",(n-4)*2/3-(n-2)/3);
		}
	}
	return 0;
}
  • 正解代码
点击查看代码(正解代码)
#include<stdio.h>
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		printf("%d\n",(n-3)/3-1);
	}
	return 0;
}
posted @ 2022-10-04 20:31  LZH_03  阅读(29)  评论(0编辑  收藏  举报