Working Week 题解
题目大意
一周有 \(n\) 天,有三天休息日,其中第 \(n\) 天一定休息。现需要安排剩下的两个休息日,要求:
-
不能使得休息日相邻。
-
这两个休息日将 \(n-1\) 天分成三段,记每段天数分别为 \(l1,l2,l3\)。
求最大的 \(\min(\ |l1-l2|\ ,\ |l2-l3|\ ,\ |l1-l3|\ )\)。
解题思路
可以将这 \(n\) 天想成一串格子来举例说明。
例如当 \(n=21\) 时:
蓝色:休息日(\(l1\),\(l2\),\(l3\));
紫色 \(+\ l2\):\(\ |l1-l2|\);
红色 \(+\ l3\):\(\ |l2-l3|\);
紫色 \(+\) 红色 \(+\ l2\ +\ l3\):\(\ |l1-l3|\);
可以将这 \(3\) 天的休息日分到 \(21-3\) 天的工作日中的三个点,用 \(\left\lfloor\dfrac{n-3}{3}\right\rfloor\) 来表示。但是这样会有两个休息日是相邻的,题目中条件是不能使得休息日相邻,所以可以将相邻的两个休息日之间留出一天。
两个休息日之间留出一天:
蓝色:休息日;
紫色 \(+\ l2\):\(\ |l1-l2|\);
红色 \(+\ l3\):\(\ |l2-l3|\);
紫色 \(+\) 红色 \(+\ l2\ +\ l3\):\(\ |l1-l3|\);
绿色:\(l1\) 与 \(l3\) 这两个相邻的休息日之间留出的一天;
也就是在原来的基础上减去留出来的一天。这样就可以既满足不能使得休息日相邻,又满足最大的 \(\min(\ |l1-l2|\ ,\ |l2-l3|\ ,\ |l1-l3|\ )\)。
所以,只要输出 \(\left\lfloor\dfrac{n-3}{3}\right\rfloor\ -1\) 即可。
代码
注意有多组数据!
#include<iostream>
using namespace std;
int T,n;
int main() {
cin>>T;
for (register int i=1;i<=T;++i) {
cin>>n;
cout<<(n-3)/3-1<<'\n'; //默认向下取整
}
return 0;
}