zoukankan      html  css  js  c++  java
  • 【牛客练习赛46-A】华华教奕奕写几何【二分】

    题目大意:

    题目链接:https://ac.nowcoder.com/acm/contest/894/A
    在这里插入图片描述
    给出红色部分面积,求大圆的最短直径(两小圆直径之和等于大圆直径)。


    思路:

    orz WYC,XYYdalaoorz WYC,XYY dalao反正我是没有看出开个根号就好了。
    先把问题转化为圆中的问题。
    在这里插入图片描述

    此时红色部分面积就为2s2s了。而所有圆的直径不变。
    设两个小圆的直径分别为x,yx,y,大圆的直径为mm,我们欲求
    πx2+πy2=πm22sπx^2+πy^2=πm^2-2s
    移项得
    2s=πm2πx2πy22s=πm^2-πx^2-πy^2

    2s=π(m2x2y2)2s=π(m^2-x^2-y^2)

    2sπ=m2x2y2frac{2s}{π}=m^2-x^2-y^2

    等号左边是已知的。由于要求大圆的直径最小,所以可以考虑二分mm
    有一点很显然的是,当两小圆直径差xy|x-y|越大,两小圆面积之和πx2+πy2πx^2+πy^2越大。
    所以这也是满足单调性的。可以考虑二分xx来验证直径为mm时是否合法。
    pipi保留小数点后15位。一开始保留7位被卡精度了。。。
    时间复杂度O(log2(maxlen))O(log^2(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;
    }
    
  • 相关阅读:
    python3使用PyMysql连接mysql数据库
    MySQL知识总结
    python--正则表达式
    python之多线程
    python在windows和linux环境的进程对比及进程和进程之间的通信
    python基础之生成器(generator)
    python基础之动态添加属性和方法
    [STM32F1] 【转】STM32驱动MPU6050
    51单片机怎么使用MPU6050读取角度值程序 ??
    stm32f10x_lib.h
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998184.html
Copyright © 2011-2022 走看看