落谷试题(一元三次方程的求解)
题目描述
有形如:a x^3 + b x^2 + c x + d = 0 这样的一个一元三次方程。给出该方程中各项的系数
(a,b,c,da,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在 -100−100 至
100100 之间),且根与根之差的绝对值 \ge 1≥1。要求由小到大依次在同一行输出这三个
实根(根与根之间留有空格),并精确到小数点后 2 位。
第一种方法 二分法
代码附上:
import java.io.*;
import java.text.*;
import java.util.*;
public class Main{
public static double a, b, c, d;
public static double f(double x0) {
return a * x0 * x0 * x0 + b * x0 * x0 + c * x0 + d;
}// 这个方法用来求出函数运算的结果
// 导数
public static double f1(double x0) {
return 3 * a * x0 * x0 + 2 * b * x0 + c;
}// 求出导数运算的结果
// 求切线与x轴的交点值
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
a = sc.nextDouble();
b = sc.nextDouble();
c = sc.nextDouble();
d = sc.nextDouble();
int count = 0;
DecimalFormat df = new DecimalFormat("#0.00");
for (int i = -100; i < 100; i++) {
double left = i;
double right = i + 1;
if (f(left) == 0) {
System.out.print(df.format(left) + " ");
} else if (f(left) * f(right) < 0) {
while ((right - left) >= 0.001) {
double mid = (left + right) / 2;
if (f(mid) * f(left) <= 0)
right = mid;
else
left = mid;
}
System.out.print(df.format(right) + " ");
/*
* x0 = right; do { x = x0; x0 = x - f(x) / f1(x); } while (Math.abs(x - x0) >=
* (Math.pow(10, -6) * (Math.E))); System.out.print(df.format(x0) + " ");
*/
}
}
}
}
这里用到了DecimalFormat类,用来规范输出到小数点后两位(此类需要导入java.text.*)
当然还有另外一种保留小数点后两位的方法:
System.out.print(String.format("%.2f",0.33333));类似于C语言输出保留小数位
第二种方法 牛顿迭代法
代码附上:
package demo;
import java.text.DecimalFormat;
import java.util.Scanner;
public class 牛顿迭代法 {
// 牛顿迭代法的思想:先缩小根的范围位于两个极值点之间,再通过极值点附近的切线与x轴的交点做垂线,再在垂线与直线的交点做切线以此类推,无线逼近
// 下面用牛顿迭代法求一个三次方程的解
public static double a, b, c, d;
public static double f(double x0) {
return a * x0 * x0 * x0 + b * x0 * x0 + c * x0 + d;
}// 这个方法用来求出函数运算的结果
// 导数
public static double f1(double x0) {
return 3 * a * x0 * x0 + 2 * b * x0 + c;
}// 求出导数运算的结果
// 求切线与x轴的交点值
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
a = sc.nextDouble();
b = sc.nextDouble();
c = sc.nextDouble();
d = sc.nextDouble();
double x, x0;
DecimalFormat df = new DecimalFormat("0.00");
for (int i = -100; i < 100; i++) {
double left = i;
double right = i + 1;
if (f(left) == 0) {
System.out.print(df.format(left) + " ");
} else if (f(left) * f(right) < 0) {
/*
* while ((right - left) >= 0.001) { double mid = (left + right) / 2; if (f(mid)
* * f(left) <= 0) right = mid; else left = mid; } if (count < 3) {
* System.out.print(df.format(right) + " "); count++; } else
* System.out.print(df.format(right));
*/
x0 = right;
do {
x = x0;
x0 = x - f(x) / f1(x);
} while (Math.abs(x - x0) >= (Math.pow(10, -6) * (Math.E)));
System.out.print(df.format(x0) + " ");
}
}
}
}
牛顿迭代法:先缩小根的范围位于两个极值点之间,再通过极值点附近的切线与x轴的交点做垂线,再在垂线与曲线的交点做切线以此类推,无线逼近