• 牛吃草_二分法


    Description

    农夫有一个长满草的(x0, y0)为圆心,r为半径的圆形牛栏,他要将一头牛栓在坐标(x1, y1)栏桩上,但只让牛吃到一半草,问栓牛鼻的绳子应为多长?

    Input

    输入一个T,表示T组测试数据
    下面T行每行五个整数 x0, y0, x1, y1, r 所有数据的绝对值小于1e5

    Output

    每组测试数据输出绳子长度,保留4位小数

    Sample Input

    2
    0 0 0 0 2
    0 0 10 10 2
    

    Sample Output

    1.4142
    14.1892

    【思路】

    while(rt-lt>eps)二分法,无限逼近
    #include<iostream>
    #include<string.h>
    #include<math.h>
    #include<stdio.h>
    using namespace std;
    const double pi=acos(-1.0);
    const double eps=1e-8;
    double get_s(double mid,int r,int d,double a,double b)//计算面积
    {
        return mid*mid*a-mid*mid*sin(a)+r*r*b-r*r*sin(b);
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            double x0,y0,x1,y1,r;
            scanf("%lf%lf%lf%lf%lf",&x0,&y0,&x1,&y1,&r);
            double d=sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0));
            double lt=d,rt=sqrt((d*d)+(r*r));
    
             if(d+r/(sqrt(2))-r<eps)//如果两个圆心重合,则满足所求R=r/sqrt(2);
              {
                  printf("%.4f
    ",1.0*r/sqrt(2));
                  continue;
              }
    
            double s=pi*r*r;
            double mid=0.0;
            while(rt-lt>eps)//二分
            {
                mid=(lt+rt)/2.0;
    
                double a=2*acos(((mid*mid)+(d*d)-(r*r))/(2.0*mid*d));//求圆心角a
                double b=2*acos(((d*d)+(r*r)-(mid*mid))/(2.0*d*r));//求圆心角b
    
                double ss= get_s(mid,r,d,a,b);
                if(ss-s>eps)
                    rt=mid-eps;
                else lt=mid+eps;
            }
            printf("%.4f
    ",mid);
    
        }
    
        return 0;
    }
  • 相关阅读:
    Centos7 安装MySQL 5.7 (通用二进制包)
    test
    test
    Windows Live Writer离线写CSDN博客
    Windows Live Writer离线写CSDN博客
    Oracle单引号双重角色——字符串引用与转义
    Oracle单引号双重角色——字符串引用与转义
    Kettle实现数据库迁移
    Kettle实现数据库迁移
    kettle实现数据库迁移----多表复制向导
  • 原文地址:https://www.cnblogs.com/iwantstrong/p/6102753.html
Copyright © 2020-2023  润新知