NOI(1.11编程基础之二分查找-02:二分法求函数的零点)

在我们的编程学习中,遇到了一些问题需要将一个大规模的问题分解成几个较小规模的问题,通过对较小规模问题的求解达到对整个问题的解,这种方法叫做分治法,而在分治法中又衍生出来了一个小方法,叫做二分查找,相信很多"高人"看着十分的眼熟,没错,这也就是数学中求开根的一种方法:二分法;

首先,我们来看看这次的问题:

NOI(1.11编程基础之二分查找-02:二分法求函数的零点)

这道题虽然可以直接输出答案,但我认为没有人会傻傻的去求这个根的具体数值的;

让我来依次为大家解读题目:

首先,函数f(x)已经在题目中为大家表示出来了,我在给大家发一次:f(x) = x5-15*x4+85*x3-225*x2+274*x-121

接着,题目中告诉大家:已知 f(1.5) > 0 , f(2.4) < 0 且方程 f(x) = 0 在区间 [1.5,2.4] 有且只有一个根

所以,我们可以知道这道题的答案,就只有一个

接下来进入代码部分:

我的思路很简单:既然题目中已经给出了f(x)的范围(2.4>=f(x)>=1.5),那我就设两个数,x=1.5,y=2.4;

NOI(1.11编程基础之二分查找-02:二分法求函数的零点)

接着,运用二分法中最重要的部分:将问题分成两个部分进行讨论:

NOI(1.11编程基础之二分查找-02:二分法求函数的零点)
可以看到,我将(x+y)/2所得的结果就是它们的中点;

接着,我定义了一个函数:ld;

NOI(1.11编程基础之二分查找-02:二分法求函数的零点)

可以看到我将题目中所叙述的f(x) = x5-15*x4+85*x3-225*x2+274*x-121转化为了c=(m*m*m*m*m)-(15*m*m*m*m)+(85*m*m*m)-(225*m*m)+(274*m)-121;

这是为了求出c的值;

接着,我又定义了一个数:f=ld(z);

这是为了求出函数的具体值;

最后,我判断了f与0的大小,并“无限”的进行判断:

NOI(1.11编程基础之二分查找-02:二分法求函数的零点)

值得提一下的是:

if(f<1e-7&&f>-1e-7) {printf("%.6lf",x);break;}
        else if(f>0) x=z;
        else y=z;

这段代码,表示比较f与0的大小,

如果f=0,就输出x;

如果f>0,就使x=z,再次比较;

如果f<0,就使y=z,再次比较;

最后,结果为NOI(1.11编程基础之二分查找-02:二分法求函数的零点)

完整的代码如下:

NOI(1.11编程基础之二分查找-02:二分法求函数的零点)