牛吃草_二分法

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\n",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\n",mid);

    }

    return 0;
}
时间: 2024-12-17 17:34:41

牛吃草_二分法的相关文章

牛吃草问题

如图所示,一块正方形草地被分为完全相同的四块以及中间的阴影部分.已知草一开始是均匀分布,且以恒定的速度均匀生长.但如果某块地上的草被吃光,就不再生长(因为草根也被吃掉了).老农先带着一群牛在1号草速度均匀生长.但如果某块地上的草被吃光,就不再生长(因为草根也被吃掉了).老农先带着一群牛在1号草地上吃草,两天后把1号草地上的草全部吃完(这期间其他的草地的草正常生长).之后他让一半牛在2号草地上吃草,另一半在3号草地上吃草,结果又过了6天,这两个草地上的草也全部吃完.最后,老农把3/5的牛放在阴影草

模拟水题,牛吃草(POJ2459)

题目链接:http://poj.org/problem?id=2459 题目大意:有C头牛,下面有C行,每头牛放进草地的时间,每天吃一个草,总共有F1个草,想要在第D的时候,草地只剩下F2个草. 解题思路:模拟啊,就像砍树一样的问题,把每天失去的草计算出来,从最后一天往前推. #include <cstdio> #include <cstring> int C,F1,F2,D; int a[2005]; int main() { while (scanf("%d%d%d%

bzoj1742[Usaco2005 nov]Grazing on the Run 边跑边吃草*&amp;&amp;bzoj3074[Usaco2013 Mar]The Cow Run*

bzoj1742[Usaco2005 nov]Grazing on the Run 边跑边吃草 bzoj3074[Usaco2013 Mar]The Cow Run 题意: 数轴上有n棵草,牛初始在L位置(bzoj3074的牛初始在1位置),每移动一个单位需要+1s.而每过1s没吃的草腐败度会+1,问吃完所有草的最小腐败度.n≤1000. 题解: 很神的dp.f[l][r][0/1]表示从第l棵草吃到第r棵草,之后到达l/r.则 f[l][r][0]=min(dfs(l+1,r,0)+(n-r+

狼为什么被逼去吃草?

有一天,狮子让一只豹子管理10只狼,并给他们分发食物.豹子领到肉之后,把肉平均分成了11份,自己要了一份,其他给了10只狼. 这10只狼都感觉自己分的少,合起伙来跟豹子唱对台戏.虽然一只狼打不过豹子,但10只狼豹子却没法应付了.豹子灰溜溜的找狮子辞职.狮子说:今后,看我的! 第二天,狮子把肉分成了11份,大小不一,自己先挑了最大的一份,然后傲然对其他狼说:你们自己讨论怎么分这些肉. 为了争夺到大点的肉块,狼群沸腾了,恶狠狠的互相攻击,全然不顾自己连平均的那点肉都没拿到.豹子钦佩的问狮子,这是什么

有一片1000*1000的草地,小易初始站在(1,1)(最左上角的位置)。小易在每一秒会横向或者纵向移动到相邻的草地上吃草(小易不会走出边界)。大反派超超想去捕捉可爱的小易,他手里有n个陷阱。第i个陷阱被安置在横坐标为xi ,纵坐标为yi 的位置上,小易一旦走入一个陷阱,将会被超超捕捉。你为了去解救小易,需要知道小易最少多少秒可能会走入一个陷阱,从而提前解救小易。 输入描述: 第一行为一个整数n

有一片1000*1000的草地,小易初始站在(1,1)(最左上角的位置).小易在每一秒会横向或者纵向移动到相邻的草地上吃草(小易不会走出边界).大反派超超想去捕捉可爱的小易,他手里有n个陷阱.第i个陷阱被安置在横坐标为xi ,纵坐标为yi 的位置上,小易一旦走入一个陷阱,将会被超超捕捉.你为了去解救小易,需要知道小易最少多少秒可能会走入一个陷阱,从而提前解救小易. 输入描述: 第一行为一个整数n(n ≤ 1000),表示超超一共拥有n个陷阱. 第二行有n个整数xi,表示第i个陷阱的横坐标 第三行

BZOJ 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草( dp )

dp... -------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i ) #define clr( x , c ) memset( x ,

BZOJ 1742 Usaco2005 nov Grazing on the Run 边跑边吃草 动态规划

题目大意:给定一个数轴,初始在位置p,有n坨草(n≤3000),约瑟芬需要吃掉所有的草,定义一坨草的腐败值为吃掉的时间,求最小腐败值之和 容易证明任何时刻约瑟芬吃掉的草都是一个区间.(废话,难道还能路过草不吃?) 因此令fi,j,k表示已经吃掉了以i开头的j坨草,当前在左端点/右端点的最小腐败值之和(包括被吃掉的和未被吃掉的,当然被吃掉的腐败值就不会再涨了) DP方程自己YY吧 注意内存 #include <cstdio> #include <cstring> #include &

bzoj 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草【区间dp】

挺好的区间dp,状态设计很好玩 一开始按套路设f[i][j],g[i][j]为吃完(i,j)区间站在i/j的最小腐败值,后来发现这样并不能保证最优 实际上是设f[i][j],g[i][j]为从i开始吃j个,站在这段区间的左/右端点的 * 最小所有草增加的腐败值 * ,因为这些腐败之最后也是要算进去的,所以直接夹在里面就可以保证最优 #include<iostream> #include<cstdio> #include<cstring> #include<algo

Day5_递归_二分法

递归调用: 在调用一个函数的过程中,直接或间接的调用函数本身. def func(): print('from func') 间接调用: def foo(): print('form foo') bar() def bar(): print('form foo') foo() 递归都是有次数限制的. 问5个人年龄,第五个比第四个大2岁,以此类推,第一个18岁. def age(n): if n ==1: return 18 return age(n-1)+2 print(age(5)) 递归的执