分治法求解方程的解

问题描述  有形如:ax3+bx2+cx+d=0  这样的一个一元三次方程。给出该方程中各项的系数

(a,b,c,d  均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),

且根与根之差的绝对值>=1。

要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后5位。

提示:记方程f(x)=0,若存在2个数x1和x2,且x1<x2,f(x1)*(x2)<0,则在(x1,x2)之间一定有一个根。

样例

输入:1   -5   -4   20

输出:-2.00   2.00   5.00


分析:由题意知(i,i+1)中若有根,则只有一个根,我们枚举根的值域中的每一个整数x(-100≤x≤100),设定搜索区间[x1,x2],其中x1=x,x2=x+1。若:

⑴f(x1)=0,则确定x1为f(x)的根;

⑵f(x1)*f(x2)<0,则确定根x在区间[x1,x2]内。

⑶f(x1)*f(x2)>0,则确定根x不在区间[x1,x2]内,设定[x2,x2+1]为下一个搜索区间;

若确定根x在区间[x1,x2]内,采用二分法,将区间[x1,x2]分成左右两个子区间:

左子区间[x1,x]和右子区间[x,x2](其中x=(x1+x2)/2)。如果f(x1)*f(x)≤0,

则确定根在左区间[x1,x]内,将x设为该区间的右界值(x2=x),继续对左区间进行对分;

否则确定根在右区间[x,x2]内,将x设为该区间的左界值(x1=x),继续对右区间进行对分;

上述对分过程一直进行到区间的间距满足精度要求为止(即x2-x1<0.000005)。此时确定x1为f(x)的根。


#include <iostream>
#include <time.h>
using namespace std;
const double e=0.00001;
//函数 f(x)=x3-5x2-4x+20
double fx(double x)
{
	double x2=x*x;
	double x3=x2*x;
	return x3-5*x2-4*x+20;
}
//解方程
void findx()
{
	double x[10]={0};
	int k=0,m=0;
	double low,high;
	for(int i=-10;i<10;i++)
	{
		low=i;
		high=i+1;
		//对每个区间进行求解
		while(high-low>e)
		{
			double  mid=(low+high)/2;
			if(fx(low)*fx(mid)<=0)
				high=mid;
			else if(fx(mid)*fx(high)<=0)
				low=mid;
			else//此区间无解
				break;
		}
		if(high-low<=0.01)//找到了一个解
		{
			x[k++]=low;
		}
		  if (k > 1 && abs(x[k-1] - x[k-2]) < e)//消除重复的解
            k--;
	}
	for(int i=0;i<3;i++)
		cout<<x[i]<<endl;

}

void main()
{
	findx();
	system("pause");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值