HDU1969 Pie

来源:互联网 发布:淘宝怎么使用农村淘宝 编辑:程序博客网 时间:2024/06/10 10:11

老实说一开始还没把题目意思看懂。。。。导致在样例纠结了好久。。

不过呢,后来就算把题目意思弄懂了,也还是不知道怎么做。。。

最后发现是二分。。想了一会儿,发现这个和那个求函数零点的问题有相似的地方。


 ① 函数求零点的判定方法是通过判断mid的函数值的正负来决定怎样收缩界限,举个斜率大于0的直线的例子,

假若mid处的函数值小于零,那么就是down=mid向上收缩,也就是判断当自变量取mid的时候,我们的反映当前状态

的状态函数F(mid)是否满足某一谓词P(F(mid)),通过P(F(mid))的真值来决定收缩界限的方向,在这里即是sgn(F(mid))。

    而这个问题和零点相似的地方是这里也是需要找到某一个值X来使得谓词P(X)成立这个谓词便是“在每个人分到X体

积的蛋糕的情况下能够满足题目的条件”,当然了,题目所求的是最大值,也就是这个最大值处于满足P(X)的区间的最右

边,此时X再大一点点便会不满足条件。这和求函数零点的情况在本质上是一样的。



因此我们只需要像求函数零点那样来找即可,不过因为题目的原因,这个点是肯定存在的,只需要最大的蛋糕和0之

间二分找即可。


#include<cstdio>using namespace std;int n, f, tem;const double PI = 3.1415926535897;double arr[10010], down_volume, up_volume, mid_volume;int main(){int t;scanf("%d", &t);while (t--){scanf("%d%d", &n, &f); ++f;for (int i = 0; i < n; ++i)scanf("%d", &tem), arr[i] = tem*tem*PI, up_volume = (up_volume>arr[i]) ? up_volume : arr[i];down_volume = 0, mid_volume = (up_volume + down_volume) / 2;while (up_volume - down_volume >= 1E-6){tem = 0;for (int i = 0; i < n; ++i)tem += static_cast<int>(arr[i] / mid_volume);if (tem >= f)down_volume = mid_volume;elseup_volume = mid_volume;mid_volume = (up_volume + down_volume) / 2;}printf("%.4lf\n", mid_volume); up_volume = 0;}return 0;}


0 0
原创粉丝点击