zoukankan      html  css  js  c++  java
  • Codevs 1038 一元三次方程求解 NOIP 2001(导数 牛顿迭代)

    1038 一元三次方程求解 2001年NOIP全国联赛提高组
    时间限制: 1 s
    空间限制: 128000 KB
    题目等级 : 白银 Silver
    题目描述 Description
    有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。
    提示:记方程f(x)=0,若存在2个数x1和x2,且x1

    /*
    导数+勘根定理+牛顿迭代.
    先对函数求导,f'(x)=3ax^2+2*bx+c.
    然后直接求根公式求f'(x)=0的点,也就是函数极点.
    (我们可以顺便求一下凸形函数极值hhh)
    这题保证有三个不定根,所以有两个单峰. 
    我们分别设这两个点为p,q.
    然后显然的必有三个根分别在[-100,p),[p,q],(q,100]三个区间内
    (两极点间必定存在零点,勘根定理).
    然后用神奇的牛顿迭代法多次迭代就好了.
    证明请自行百度,本蒟蒻只能感性的认识orz.
    */
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define eps 1e-4
    using namespace std;
    double x1,x2,x3,a,b,c,d;
    double f(double x){return a*x*x*x+b*x*x+c*x+d;}
    double df(double x){return 3*a*x*x+2*b*x+c;}
    double slove(double l,double r)
    {
        double x,x0=(l+r)/2;
        while(abs(x0-x)>eps)
          x=x0-f(x0)/df(x0),swap(x0,x);
        return x;
    }
    int main()
    {
        cin>>a>>b>>c>>d;
        double p=(-b-sqrt(b*b-3*a*c))/(3*a);
        double q=(-b+sqrt(b*b-3*a*c))/(3*a);
        x1=slove(-100,p),x2=slove(p,q),x3=slove(q,100);
        printf("%.2lf %.2lf %.2lf",x1,x2,x3);
        return 0;
    }
  • 相关阅读:
    redis info命令中各个参数的含义
    mogndb 慢查询
    一分钟看懂Docker的网络模式和跨主机通信
    解决Nginx出现403 forbidden (13: Permission denied)报错的四种方法
    dva学习---effects异步中通过select获取当前的state
    golang json数组拼接
    golang mongodb查找find demo
    React从入门到精通系列之(14)refs和DOM元素
    选择——ERP信息系统选型
    企业库存资产的帐实管理思考
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068099.html
Copyright © 2011-2022 走看看