落谷试题 P1024 [NOIP2001 提高组] 一元三次方程求解

落谷试题(一元三次方程的求解)

题目描述

有形如: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轴的交点做垂线,再在垂线与曲线的交点做切线以此类推,无线逼近

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值