欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C

程序员文章站 2022-07-14 07:56:59
...

蚂蚁是勤劳的动物,他们喜欢挑战极限?现在他们迎来了一个难题!蚂蚁居住在图书馆里,图书馆里有大量的书籍。书是形状大小质量都一样的矩形。蚂蚁要把这些书摆在水平桌子的边緣。蚂蚁喜欢整洁的布置,所以蚂蚁规定书本必须水平摆放,宽必须平行于桌緣(如图),而且不允许同一高度摆多本书。
https://cdn.luogu.org/upload/pic/30575.png
蚂蚁想要让书本伸出桌子边缘尽量远,同时不让书因为重力垮下来。它们己经用不知道什么方法测出了书的长度M(如图)。如果总共有N本书,请你帮忙计算如何摆放使得最多水平伸出桌缘多远。你不用考虑蚂蚁用什么方法搭建这堆书。
如果某本书以上的所有书的重心的竖直射影不在这本书上,或者正好落在在这本书的边界上,那么这堆书是不稳定的,会因为重力而垮下来。
考虑以下的假设:

不考虑地球自转,重力系数也不因高度改变;
书是质量均匀,质地坚硬的理想二维物体;
在不会垮的前提下,每本书的位置坐标可以是任意实数。

    Input
    第一行正整数 N M

    Output
    一行(有换行符),L,表示水平延伸最远的整数距离 (不大于答案的最大整数)

    Sample Input
    样例

#1
Input: 1 100
Output: 49

#2
Input: 2 100
Output: 74

    Sample Output
     N <= 10^18
数据保证答案 < 10^6
// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
long long n, m, ans;
double f = 0, eps = 1e-6;
int main() {
    int i;
    scanf("%lld%lld", &n, &m);
    if (n >= 1e7) f = (log(n) + 0.5772156649) / 2;
    else {
        for (i = 2; i <= n * 2; i += 2) f += 1.0 / i;
    }
    ans = m * f - eps;
    printf("%lld\n", ans);
    return 0;
}

发现是调和级数,直接套公式哦
(有点像phi函数)
然后我们就可以考虑用调和级数极限公式可能有精度问题
不过(log(n) + 0.5772156649) / 2在大范围内还是没有问题的
所以我们暴力时注意long double的转换
于是考虑小数据直接暴力,大数据到套公式…
注意输出的是注意精度…
需要减去一个实数,不影响精度
唉!处处要考虑精度
其他真的没有需要讲的吧,已经够清楚了吧。。。
放上代码

#include <bits/stdc++.h>
#define LL long long
#define db double
using namespace std;
inline LL read(){
    LL x = 0,f = 1; char c = getchar();
    while (c != EOF && !isdigit(c)) {if (c == '-') f = -1;c = getchar();}
    while (c != EOF && isdigit(c)) {x = x * 10 + c - '0';c = getchar();}
    return x * f;
}
inline void write(LL x){
    int k = 0;char put[40];
    if (!x) putchar('0');
    if (x < 0) putchar('-'),x = -x;
    while (x)  put[++k] = (x % 10) + '0',x /= 10;
    while (k)  putchar(put[k]),--k;
    putchar('\n');
}

LL n,m,ans;
db f = 0,eps = 1e-6;

int main(){
    n = read(),m = read();
    if (n >= 1e7) f = (log(n) + 0.5772156649 )/ 2;
    else for (int i = 2; i <= n*2; ++i,++i ) f += 1.0 / i;
    ///小数据一定要暴力!上面只是个近似公式!!!!
    ans = m * f - eps;
    write(ans);
    return 0;
}

这题…

一道极好的初中物理+(貌似是高中?)数学题。
通过初中物理的学习,我们知道了杠杆平衡。
通过打表/手算找规律,发现答案 = (1 / 2 + 1 / 4 + … 1 / (2n)) * m.
貌似是调和级数H(n) / 2???
ok,精度爆炸qwq.
好了,我们baidu一下,发现有个公式: (ln(n) + 0.5772156649) / 2.
怎么还是WA???
回顾下题面:
“如果某本书以上的所有书的重心的竖直射影不在这本书上,或者正好落在在这本书的边界上,那么这堆书是不稳定的,会因为重力而垮下来。”
所以。。。 我们的答案不能正好取到,还要减去一个重心的位移。。。
减去一个很小的实数(不影响精度)即可。
代码: