NOip2001 一元三次方程
Posted zi-nai-boboyang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOip2001 一元三次方程相关的知识,希望对你有一定的参考价值。
一元三次方程,二分法求解,根据题目要求根的范围【-100,100】
考虑在什么样的区间内会有根,由于题目给出了所有的根都在-100到100之间,
且根与根之间的差不小于1的限制条件,可知,
在[-100,-99],[-99,-98],…[99,100],[100,100]这201个区间内,
每个区间内至多只能存在一个根,这样除去区间[100,100],[-100,-100]外,
其他区间[a,a+1],要么f(a)=0,要么f(a)×f(a+1)<0时这个方程在此区间内才有解。
2.求方程的根
确定了方程f(x)=0在区间(a,b)内如果有且只有一个根,那么我们可以有逐步缩小根可能存在的范围的方法确定出某精度下根的数值。本题规定根的精度是0.01,下面采用二分法求区间(a,b)内方程的根,过程如下:
(1)取当前可能存在解的区间(a,b);
(2)若a+0.001>b或 f((a+b)/2)=0,则可确定根为(a+b)/2并退出过程;
(3)若f(a)×f((a+b)/2)<0,则根在区间(a, (a+b)/2)中,
故对区间(a, (a+b)/2)重复该过程;
(4)若f(a)× f((a+b)/2)>0,则必然有 f((a+b)/2)×f(b)<0,
也就是说根在((a+b)/2,b)中,应该对此区间重复该过程。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//本题中特别注意的函数abs(),abs是取整数的绝对值,返回整数值
//fabs()才是用来求浮点数的绝对值,返回浮点数
float a,b,c,d;
float f(float x) //返回函数值的函数
return a*x*x*x+b*x*x+c*x+d;
int main(int argc, char *argv[])
float i,x,x1,x2;
int ans=0; //用于统计解的个数
scanf("%f%f%f%f",&a,&b,&c,&d);
// printf("%.2f\n",f(-0.5));
for(i=-100;i<100;i++)
if(abs(f(i)*f(i+1))==0) //首先判定f(i)=0的解
if(abs(f(i))==0)
x=i;
ans++;
printf("%.2f ",x);
else if(f(i)*f(i+1)<0) //满足解在范围[i,i+1]内的条件
x1=i;
x2=i+1;
x=(x1+x2)/2;//若解在[i,i+1]内,采用二分法,查找解
while(fabs(f(x))>0.000001&&(x1+0.001)<x2)
//由于实数运算的误差,判断x是否满足方程f(x)=0
//应用条件表达式 fabs(f(x))<0.000001来判断,否则将失根。
// printf("%.2f\n",f(x));
if(f(x)*f(x1)>0)//若f(x)*f(x1)>0,则根在[x,x2]范围内
x1=x; //修改根的范围
x=(x1+x2)/2;
// printf("%.2f %f\n",x,f(x));
else
x2=x; //否则f(x)*f(x1)<=0,则根在[x1,x]范围内
x=(x1+x2)/2;
// printf("%.2f %f\n",x,f(x));
ans++;
printf("%.2f ",x);//输出在[i,i+1]内,使用二分法找到的解
if(ans>=3) break;
return 0;
以上是关于NOip2001 一元三次方程的主要内容,如果未能解决你的问题,请参考以下文章
二分查找(vijos1116一元三次方程求解NOIP2001第一题)
codevs 1038 一元三次方程求解 NOIP2001提高组