目录
1 问题描述
问题描述
利用标准库中的cos(x)和fabs(x)函数实现arccos(x)函数,x取值范围是[-1, 1],返回值为[0, PI]。要求结果准确到小数点后5位。(PI = 3.1415926)
提示:要达到这种程度的精度需要使用double类型。
提示:要达到这种程度的精度需要使用double类型。
样例输入
0.5
样例输出
数据规模和约定
-1 <= x <= 1, 0 <= arccos(x) <= PI。
2 解决方案
本题借用反三角函数,考查我们对于二分法思想的运用。
易知cos(a) = b,那么arccos(b) = a。那么现在求取arccos(x),设其结果为result。那么当cos(result)无穷趋近x值时,则说明,result则为我们需要求取的值,下面请看一张示意图:
这题提交了好几次,因为觉得自己思路是没有问题,但是,提交后的评分结果一直为33分,后来用Java给定的Math.acos()函数,对比后,发现是自己设定的取值范围不够精确,导致计算结果偏大。
即:Math.abs(judge) > 0.000000000000001。
第一次做的时候,是这样:Math.abs(judge) > 0.000001。导致当x取1或者-1时误差太大,后来自己仔细一想,这个不能决定最终结果保留五位小数的误差。
给我的教训:下次碰到计算精确值时,尽量做到计算能够达到最精确为准,这样也可以防止自己没有考虑仔细,导致相关意外情况发生。
经过修改后的代码,运行评分为100分。
具体代码如下:
import java.util.Scanner; public class Main { public final static double PI = Math.PI; public void getArcCos(double x) { double i = 0, j = PI; double result = (i + j) / 2; double judge = Math.cos(result) - x; double temp; while(Math.abs(judge) > 0.000000000000001) { result = (i + j) / 2; temp = Math.cos(result); if(temp - x > 0) { i = result; } else { j = result; } judge = Math.cos(result) - x; } System.out.printf("%.5f", result); return; } public static void main(String[] args) { Main test = new Main(); Scanner in = new Scanner(System.in); double x = in.nextDouble(); if(x < -1 || x > 1) return; test.getArcCos(x); } }