题目链接 : 点击查看
题目描述 :
给定一个浮点数 n,求它的三次方根(保留6位小数)。
数据范围 :
−10000 ≤ n ≤10000
输入输出 :
输入
1000 . 00
输出
10 . 000000
题目分析 :
方法一 :根据n的范围直接将区间左右端 l 和 r 分别赋值为 -10000、10000, 然后通过比较mid 的三次方与 n 的大小从而对区间不断进行二分,直到区间大小 l - r <= le-8。
代码 :
#include<iostream>
#include<cstdio>
using namespace std;
int main() {
double n;
scanf("%lf", &n);
double l = -10000, r = 10000;
while (r - l > 1e-8) {
double mid = (l + r) / 2;
if (mid * mid * mid > n) {
r = mid;
}
else {
l = mid;
}
}
printf("%lf",l);
return 0;
}
方法二 :此方法可相比于方法一区间范围要小,但要对n分情况进行处理。首先先考虑n的正负情况,如果n为负数则将n置为其绝对值,并通过flag记录其符号,后则简化为只对非负数进行处理。然后在判断n为小于1的数还是大于等于1的数,如果n小于1则其三次方根比原数要大,此时确定区间[ l , r ]为[ 0 , 1 ] ,反之则确定区间为 [ 0 , n ]。综上,右边界 r = max (1.0 , n);
代码 :
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<iomanip>
using namespace std;
int main() {
int flag = 1;
double n;
cin>>n;
if (n < 0) {
flag = -1;
n = -n;
}
double l = 0, r = max(n, 1.0);
while (r - l > 1e-8) {
double mid = (l + r) / 2.0;
if (mid * mid * mid > n) {
r = mid;
}
else {
l = mid;
}
}
if(flag == 1)
cout<< fixed << setprecision(6) << l;
else
cout<< fixed << setprecision(6) << -l;
return 0;
}
--------------------------------------------------------------------------
在此给出浮点数二分的模板
bool check(double x) {/* ... */} // 检查x是否满足某种性质
double bsearch_3(double l, double r)
{
const double eps = 1e-6; // eps 表示精度,取决于题目对精度的要求
while (r - l > eps)
{
double mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid;
}
return l;
}