uva 10668(计算几何+二分)


给你三个值,L.n,C,;L表示棍子的原长,n,C都代表系数,且该棍子受热后,会产生弯曲,弯曲后的棍子的长度为L' = (1+n*C)*L,现在要你求弯曲的幅度(弯曲幅度不会超过原来的一半)。


解题思路:

设圆心角为rad,半径为r,所以r = L/(2sin(rad)),r = (L'/(2rad));所以可以得到表达式 L/(2sin(rad))= (L'/(2rad)) ,且rad∈[0,PI].求解,注意精度问题

开始时1e-8不过 , 调到1e-12次就过了大哭


原题地址:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=494&page=show_problem&problem=1609

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define eps 1e-12
#define PI acos(-1.0)
double A,C,B;
int dcmp(double x){
    if(fabs(x)<eps){
        return 0;
    }
    return x<0?-1:1;
}
double f(double x){
	return B*sin(x) - x*A;
}
double solve(){
    double tmp0 = B-PI*A/2;
	int flag = dcmp(tmp0);
	double Mid,MidVal;
	if(flag<0){
	double	L = acos(A/B);
	if(dcmp(L)==0){
          L+=eps;
	}
	double 	R = PI/2+eps;
		while(dcmp(R-L)==1){
			Mid = L + (R-L)/2;
            MidVal = f(Mid);
			if(dcmp(MidVal)>0)L = Mid;
			else R = Mid;
		}
		double r = B/(2*L);
		return r -  r*cos(L);
	}
	else if(flag==0){
         return A/2; 
	}
	else {
       return B/2;     
	}
}
int main(){
    double L,n;
    while(scanf("%lf%lf%lf",&L,&n,&C)!=EOF){
        
        if(dcmp(L)<0&&dcmp(n)<0&&dcmp(C)<0)break;
        B = (1+n*C)*L;
        A = L;
        double ans = solve();
        printf("%.3f\n",ans);
        
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值