TIMUS1503(高阶代数方程求根)

problem

Every New Russian wants to give his children all the best. The best education, in particular. For example, Kolyan has asked the math teacher to teach his son to solve not only quadratic equations, but also cubic ones, and quaternary ones, and altogether all the equations there are. The teacher knows that equations of degrees higher than five cannot be solved in radicals in the general form. But to solve equations up to the fifth degree is also very hard. It is better to check solutions using a computer. Here your help is needed.

Input

The first line contains the degree of a polynomial N (1 ≤ N ≤ 5). In the next N + 1 lines there are integers (-100 ≤ ai ≤ 100, a0 ≠ 0). The i+2nd line contains the ith coefficient of the polynomial a0xn + a1xn–1 + … + an.

Output

Output all real roots of the polynomial taking into account their multiplicity. The roots must be given in the ascending order. The accuracy must be not less than 10–6.

Sample

input output
2
1
-2
1

1
1

solution

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

首先对其求导,求出其导函数的所有零点,那么在导函数两个相邻的零点之间,该n次方程一定是单调的,并且最多只有一个零点,利用这个性质,我们可以二分求出这个零点。

而求出导函数的零点可以递归地做下去,直到n=1时,可以直接返回答案。

//TIMUS1503
#include
using namespace std;
typedef long long ll;
int debug_num=0;
#define debug cout<<"debug "<<++debug_num<<" :"

const double eps=1e-12;
const double inf=1e12;

inline int sign(double x){
    return x<-eps ? -1 : x>eps ;
}

//coef 系数  coef[i]=a[i]
inline double get(const vector<double> &coef,double x){//将x带入方程的值
    double e=1,s=0;//e=x^i (i=0,1,2,...,n)   coef.size():n+1
    for(int i=0;ireturn s;
}

double Find(const vector <double> &coef,int n,double lo,double hi){
    double sign_lo,sign_hi;
    if((sign_lo=sign(get(coef,lo)))==0) return lo;//lo就是零点
    if((sign_hi=sign(get(coef,hi)))==0) return hi;//hi就是零点
    if(sign_hi*sign_lo>0) return inf;//当前区间没有零点
    for(int step=0;step<100 && hi-lo>eps;++step){//标准二分
        double m=(lo+hi)*.5;
        int sign_mid=sign(get(coef,m));
        if(sign_mid==0) return m;
        if(sign_lo*sign_mid<0) hi=m;
        else lo=m;
    }
    return (lo+hi)*.5;
}

vector<double> solve(vector<double> coef,int n){
    vector<double> ret;
    if(n==1){
        if(sign(coef[1])) ret.push_back(-coef[0]/coef[1]);
        return ret;//直接求解
    }
    vector<double> dcoef(n);//求导 大小只有n(原函数是n+1)
    for(int i=0;i1]*(i+1);
    vector<double> droot=solve(dcoef,n-1);
    droot.insert(droot.begin(),-inf);
    droot.push_back(inf);//开头结尾插上-inf 和inf 方便二分  关键
    for(int i=0;i+1double tmp=Find(coef,n,droot[i],droot[i+1]);
        if(tmpreturn ret;
}

vector <double > ans;

vector <double > coef;

int main()
{
    //freopen("in.txt","r",stdin);
    //ios::sync_with_stdio(false);
    int n;
    scanf("%d",&n);
    for(int i=0;i<=n;++i){
        double tp;
        scanf("%lf",&tp);
        coef.push_back(tp);
    }
    reverse(coef.begin(),coef.end());//注意顺序看要不要逆序   coef[0]放的是x^0对应的系数

    ans=solve(coef,n);
    sort(ans.begin(),ans.end());
    for(int i=0;iprintf("%.6f\n",ans[i]);
    }
    return 0;
}

你可能感兴趣的:(-----------,数,学,-----------)