求:y=√x
1.二分法求零点
由于函数在(0,+oo)为单调函数,取值为正
yy - x = 0 设 g(y) = yy - x ,函数值在自变量y属于(0,+oo)也单调。g(0)<=0 ,g(x+1)>0 所以可在区间[0,x+1]上采用二分法
#includeconst double eps=1e-10;//精度小数点后10位
//求y=根号x
//则y^2=x
double Abs(double val) {//求val的绝对值
if (val < 0)
val = -val;
return val;
}
int main(void) {
double x;
scanf("%lf", &x);
double l = 0, r = x + 1, mid = l;
while (Abs(r - l) > eps) {//区间长度大于eps就继续二分区间
mid = (l + r) / 2;
if (mid * mid > x)
r = mid;
else
l = mid;
}
printf("%.20f", mid);
return 0;
}
二分法的时间复杂度为 log2(x/精度)
eg.
输入:2
输出:1.41421356229693630000
2.三分法求极值
求√a,需构造函数。由于 a+b>=2√(ab) [当且仅当a等于b时,原式取等]。所以构造函数:
y = x+a/x (a>0)
只有当x=√a时,y可取得极小值。然后三分区间 ( 0, a + 1],当函数求得极值时即求得横坐标 ans = x
#includeconst double eps=1e-10;//精度小数点后10位
double Abs(double val) {//求val的绝对值
if (val < 0)
val = -val;
return val;
}
double func(double a, double x){//构造的函数,在(0,+oo)上有唯一的极值
return x+a/x;
}
int main(void) {
double x;
scanf("%lf", &x);
double l = eps, r = x + 1, lm, rm;
while (Abs(r - l) > eps) {
lm = (l*2+r)/3;
rm = (r*2+l)/3;
double fl = func(x,lm);
double fr = func(x, rm);
if(fl
三分法的时间复杂度为 log1.5 (x/精度)
eg.
输入:2
输出:1.41421357309081250000