zoukankan      html  css  js  c++  java
  • 中国大学MOOC数据结构基础习题集、031、二分法求多项式单根

    首先粘一下题目:

    二分法求函数根的原理为:如果连续函数f(x)在区间[a, b]的两个端点取值异号,即f(a)f(b)<0,则它在这个区间内至少存在1个根r,即f(r)=0。

    二分法的步骤为: 

    检查区间长度,如果小于给定阈值,则停止,输出区间中点(a+b)/2;否则
    如果f(a)f(b)<0,则计算中点的值f((a+b)/2);
    如果f((a+b)/2)正好为0,则(a+b)/2就是要求的根;否则
    如果f((a+b)/2)与f(a)同号,则说明根在区间[(a+b)/2, b],令a=(a+b)/2,重复循环;
    如果f((a+b)/2)与f(b)同号,则说明根在区间[a, (a+b)/2],令b=(a+b)/2,重复循环;

    本题目要求编写程序,计算给定3阶多项式f(x)=a3x3+a2x2+a1x+a0在给定区间[a, b]内的根。

    输入格式:

    输入在第1行中顺序给出多项式的4个系数a3、a2、a1、a0,在第2行中顺序给出区间端点a和b。题目保证多项式在给定区间内存在唯一单根。

    输出格式:

    在一行中输出该多项式在该区间内的根,精确到小数点后2位。

    输入样例:
    3 -1 -3 1
    -0.5 0.5
    输出样例:
    0.33

    注意事项:

    1. 题目中要求精确到小数点后2位,因此要#define或者const一个常量,#define EPS 1e-3或者const double EPS=1e-3。用这个常量判断区间的大小。亦即当(a,b)区间长度b-a小于或等于1e-3时,终止循环。

    2. 循环过程中判断如果f((a+b)/2)等于0,则提前终止循环,并输出结果。在循环外边判断如果f((a+b)/2)不等于0,说明在循环体内并没有结果输出,而是由于区间长度过小(小于或等于1e-3)使循环终止,此时要输出(a + b) / 2。

    3. 函数的计算,使用x * (x * (a3 * x + a2) + a1) + a0要比a3*x*x*x+a2*x*x+a1*x+a0更好!

    因为这道题比较简单,注意事项也已经提前说明,因此直接粘出代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 
     4 #define EPS (1e-3)// 注意事项1
     5 using namespace std;
     6 
     7 double a3, a2, a1, a0;
     8 double func(double x);
     9 int main()
    10 {
    11     double a, b;
    12     cin >> a3 >> a2 >> a1 >> a0;
    13     cin >> a >> b;
    14 
    15     double fa = func(a);
    16     double fb = func(b);
    17     while(b - a > EPS)// 注意事项1
    18     {
    19         double mid = (a + b) /2;
    20         double fmid = func(mid);
    21         if(fmid == 0)// 注意事项2
    22         {
    23             printf("%.2lf", mid);
    24             break;
    25         }
    26         if(fa * fmid > 0)
    27         {
    28             a = mid;
    29             fa = func(a);
    30             continue;
    31         }
    32         if(fb * fmid > 0)
    33         {
    34             b = mid;
    35             fb = func(b);
    36             continue;
    37         }
    38     }
    39     if(func((a + b )/ 2) != 0)
    40         printf("%.2f\n", (a + b) / 2);// 注意事项2
    41 
    42     return 0;
    43 }
    44 double func(double x)
    45 {
    46     return  x * (x * (a3 * x + a2) + a1) + a0;// 注意事项3
    47 }

    按照惯例粘一下AC的结果:

  • 相关阅读:
    如何使用SAP Intelligent Robotic Process Automation自动操作Excel
    OpenSAML 使用引导 IV: 安全特性
    Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
    微服务架构集大成者—Spring Cloud (转载)
    Spring Cloud Eureka 服务注册列表显示 IP 配置问题
    使用 Notification API 开启浏览器桌面提醒
    SignalR 中使用 MessagePack 序列化提高 WebSocket 通信性能
    配置 Nginx 的目录浏览功能
    关于 Nginx 配置 WebSocket 400 问题
    Migrate from ASP.NET Core 2.0 to 2.1
  • 原文地址:https://www.cnblogs.com/clevercong/p/4176564.html
Copyright © 2011-2022 走看看