本文主要是介绍【牛客练习赛46-A】华华教奕奕写几何【二分】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目大意:
题目链接:https://ac.nowcoder.com/acm/contest/894/A
给出红色部分面积,求大圆的最短直径(两小圆直径之和等于大圆直径)。
思路:
o r z W Y C , X Y Y d a l a o orz\ WYC,XYY dalao orz WYC,XYYdalao反正我是没有看出开个根号就好了。
先把问题转化为圆中的问题。
此时红色部分面积就为 2 s 2s 2s了。而所有圆的直径不变。
设两个小圆的直径分别为 x , y x,y x,y,大圆的直径为 m m m,我们欲求
π x 2 + π y 2 = π m 2 − 2 s πx^2+πy^2=πm^2-2s πx2+πy2=πm2−2s
移项得
2 s = π m 2 − π x 2 − π y 2 2s=πm^2-πx^2-πy^2 2s=πm2−πx2−πy2
2 s = π ( m 2 − x 2 − y 2 ) 2s=π(m^2-x^2-y^2) 2s=π(m2−x2−y2)
2 s π = m 2 − x 2 − y 2 \frac{2s}{π}=m^2-x^2-y^2 π2s=m2−x2−y2
等号左边是已知的。由于要求大圆的直径最小,所以可以考虑二分 m m m。
有一点很显然的是,当两小圆直径差 ∣ x − y ∣ |x-y| ∣x−y∣越大,两小圆面积之和 π x 2 + π y 2 πx^2+πy^2 πx2+πy2越大。
所以这也是满足单调性的。可以考虑二分 x x x来验证直径为 m m m时是否合法。
p i pi pi保留小数点后15位。一开始保留7位被卡精度了。。。
时间复杂度 O ( log 2 ( m a x l e n ) ) O(\log^2(maxlen)) O(log2(maxlen))
代码:
#include <cstdio>
#include <cmath>
using namespace std;const double pi=3.141592653589793;
const double minn=0.00001;
double s;bool check(double x)
{double l=0.0,r=x,mid,sum;while (r-l>=minn){mid=(l+r)/2.0;sum=mid*mid+(x-mid)*(x-mid)+s;if (sum>x*x) r=mid;else l=mid;}if (x/2.0-r<=minn) return 0;return 1;
}int main()
{scanf("%lf",&s);s=s*2.0/pi;double l=0.0,r=2000000.0,mid;while (r-l>=minn){mid=(l+r)/2.0;if (check(mid)) l=mid;else r=mid;}printf("%0.3lf",l);return 0;
}
这篇关于【牛客练习赛46-A】华华教奕奕写几何【二分】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!