TIMUS1503(高阶代数方程求根)

题目

题意:

给定方程 anxn+an1xn1+...+a1x+a0=0 a n x n + a n − 1 x n − 1 + . . . + a 1 x + a 0 = 0 ,求出该方程的所有实数解

Solution:

首先对其求导,求出其导函数的所有零点,那么在导函数两个相邻的零点之间,该 n n 次方程一定是单调的,并且最多只有一个零点,利用这个性质,我们可以二分求出这个零点。
而求出导函数的零点可以递归地做下去,直到n=1时,可以直接返回答案
时间复杂度 O(n3log) O ( n 3 l o g )

Code:

//equ->equation
//d->delta
//s->sign
//rt->root
#include<bits/stdc++.h>
using namespace std;
typedef double D;
typedef vector<D> V;
const D inf=1e11,eps=1e-12;
V ans,equ;
int n,i;
D x;
inline int sgn(D x){
    return x<-eps?-1:x>eps;
}
D get(V equ,D x){
    D e=1,s=0;
    for (int i=0;i<equ.size();i++) s+=e*equ[i],e=e*x;
    return s;
}
D find(V equ,D l,D r){
    int sl,sr;
    if ((sl=sgn(get(equ,l)))==0) return l;
    if ((sr=sgn(get(equ,r)))==0) return r;
    if (sl*sr>0) return inf;
    for (;r-l>eps;){
        D m=(l+r)/2;
        int sm=sgn(get(equ,m));
        if (sm==0) return m;
        if (sl*sm<0) r=m;
        else l=m;
    }
    return (l+r)/2;
}
V solve(V equ,int n){
    V res;
    if (n==1){
        if (sgn(equ[1])) res.push_back(-equ[0]/equ[1]);
        return res;
    }
    V dequ(n);
    for (int i=0;i<n;i++) dequ[i]=equ[i+1]*(i+1);
    V drt=solve(dequ,n-1);
    drt.insert(drt.begin(),-inf);
    drt.push_back(inf);
    for (int i=0;i<drt.size()-1;i++){
        D ans=find(equ,drt[i],drt[i+1]);
        if (ans<inf) res.push_back(ans);
    }
    return res;
}
int main(){
    scanf("%d",&n);
    for (i=0;i<=n;i++) scanf("%lf",&x),equ.push_back(x);
    reverse(equ.begin(),equ.end());//注意逆序
    ans=solve(equ,n);
    sort(ans.begin(),ans.end());
    for (i=0;i<ans.size();i++) printf("%.6lf\n",ans[i]);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值