zoukankan      html  css  js  c++  java
  • Expanding Rods POJ1905 二分

    http://poj.org/problem?id=1905

    这个题目其实想到了方法一点都不难,但是一般想到方法也不过是找到了一个关于r和sita的表达式,然后进行行二分或三分求解。

    所以一般的求解显得复杂,参考了大神的解法之后,真心觉得ACM算法之路好有好长。

    简述一下大神的做法:

    大神选择了直接二分高度,通过高度和弦长推出半径,再算角度,最后与实际的弧长进行比较,并最后进行调整。

    这种算法的好处有以下几点;

    1.使用相交弦定理,一步求出半径(真不知大神怎么还会记得相交弦定理啊,这数学基础!!!!!)

    2,只在求sita时使用了一次反三角函数,不像其他的算法,反复的求三角正弦,余弦啊各种·····尽量保留了精度。

    3,突破以往的二分模式,并不求关于高度的calcu表达式,而是间接利用,以判断大小

    4,最后,我觉得最神奇的是大神在复杂的题意下,找到了一个非常简洁的单挑函数:依题长度增加做多不过一半,也就是其形成的扇形组最大不过是半圆,那么在弦长一定的时候,给一个弧高就可以确定一个园,进而可以确定这段弧长。

    反正我自己觉得这个算法很牛,不知读者怎么想,再次表达一下对这些大神们神一样的解题思路的无限敬仰。

    这是我按照思路,自己写的代码,读者应该能写出更好的:

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<cstring>
     4 using namespace std;
     5 #define eps 1e-4
     6 double l,c,ls,n,r,sita;
     7 double solve(double a,double b)
     8 {
     9     double left,right,mid;
    10     left=a;
    11     right=b;
    12     while(left+eps<right)
    13     {
    14 
    15         mid=(left+right)/2;
    16         r=l*l/8/mid+mid/2;
    17         //sita = acos(1-l*l/r/r/2);
    18         sita=2*asin(l/2/r);
    19         if(sita*r>=ls)
    20             right=mid;
    21         else
    22             left=mid;
    23     }
    24     return left;
    25 }
    26 int main()
    27 {
    28     while(~scanf("%lf%lf%lf",&l,&n,&c))
    29     {
    30         if(l<0||n<0||c<0)break;
    31         ls=l*(1+n*c);
    32         printf("%.3f
    ",solve(0,l/2));
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    Xcode4快速Doxygen文档注释 — 简明图文教程
    iOS6 旋转
    echart 判断数据是否为空
    echart tootip使用技巧
    下拉菜单自动向上或向下弹起
    前后台数据交互
    打包代码
    echart 设计宽度为百分比时,div撑不开
    无缝滚动(小鹏写)
    内置对象-Request对象
  • 原文地址:https://www.cnblogs.com/plank-george-zzo/p/3245621.html
Copyright © 2011-2022 走看看