BZOJ-2048 [2009国家集训队]书堆(物理)
题目描述
有 \(n(n\leq 10^{18})\) 本长度为 \(m\) 的书摆在水平桌面上,现在需要让书本伸出桌子边缘尽量远,同时不让书因为重力垮下来。如果某本书以上的所有书的重心的竖直射影不在这本书上,或者正好落在在这本书的边界上,那么这堆书是不稳定的,会因为重力而垮下来。求水平延伸最远的整数距离,答案 \(<10^6\)。
分析
由于下面的书的摆放不会影响上面的书是否会掉落,所以从最上面的书依次往下分析。
每一本书是否会掉落可以利用书的重力(质量分布均匀的书的重心为 \(\frac{m}{2}\) 处)对紧邻这本书下面的书的右端产生的力矩来判断。
当且仅当力矩为 \(0\) 时,第一本书刚好不会掉落且伸出的长度最大,所以 \((l_1-\frac{m}{2})Mg=0\),解得 \(l_1=\frac{m}{2}\)。
把第一本书和第二本书看成一个整体,所产生的力矩为 \(0\) 时,伸出长度最大。
解得 \(l_2=\frac{m}{4}\)。
依次类推,最终得到 \(l_n=\frac{m}{2n}\),全部加起来即为答案。
本题的数据范围非常大,小范围直接暴力,大范围使用调和级数的近似求和公式:
其中 \(\gamma\) 为欧拉常数,\(\gamma =\lim\limits_{n\rightarrow\infty}\displaystyle\int_{1}^{n}(\frac{1}{\lfloor x\rfloor}-\frac{1}{x})dx\approx 0.577215664\cdots\)。
由于本题认为正好重心落在边界上是不稳定的,所以答案还需要减一个常数。
代码
#include<bits/stdc++.h>
using namespace std;
double f,eps=1e-6;
int main()
{
long long n,m;
cin>>n>>m;
if(n>=1e7)
f=(log(n)+0.5772156649)/2;
else
{
for(int i=2;i<=2*n;i=i+2)
f=f+1.0/i;
}
long long ans=m*f-eps;
printf("%lld\n",ans);
return 0;
}
posted on 2020-12-07 13:44 DestinHistoire 阅读(67) 评论(0) 编辑 收藏 举报