timus 1503 Polynomial

已知a0,a1...an 求f(x)=a0*x^n + a1* x^n-1 +...an,使得f(x)=0的所有解。。其中1<=n<=5。。

 

我也有被卡精度的时候啊啊啊啊啊!!!。。

若要求f(x)=0,可先求f `(x)=0,由f(x)的导数的解将f(x)划分成若干段区间,这其中每段区间都是单调的,于是可以二分求零点,

那么f ` (x)=0怎么求呢?递归。

还好n<=5,不然TLE到死啊。。好像据说n>5不能解什么的。。

代码:

#include<cmath>
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
#define inf 1e12
#define eps 1e-12
using namespace std;
typedef vector<double> VI;
double get(double x,VI f){
	int i,n=f.size();
	double as=0,e=1;
	for(i=0;i<n;i++)
	    as+=e*f[i],e*=x;
	return as;
}
double bi(double l,double r,VI f){
	int i,n=f.size(),flag;
	double m,as,a,b;
	a=get(l,f);b=get(r,f);
	if(fabs(a)<eps)return l;//此处可以直接提高精度
	if(fabs(b)<eps)return r;//此处可以直接提高精度
	if(a*b>eps)return inf;
	flag=a>b?1:-1;
	while(l<r-eps){
		m=(l+r)*0.5;
		as=get(m,f);
		if(as*flag>0)l=m;
		else    	 r=m;
	}
	return m;
}
VI solve(VI now,int n){
	VI as,tmp,f;//f导数,tmp导数的解,as now的解
	as.push_back(-inf);
	if(n==1){
		as.push_back(-now[0]/now[1]);
		as.push_back(inf);
		return as;
	}
	for(int i=1;i<=n;i++)
	    f.push_back(now[i]*i);
	tmp=solve(f,n-1);
	for(int i=1;i<tmp.size();i++)
	    as.push_back(bi(tmp[i-1],tmp[i],now));
    as.push_back(inf);
	sort(as.begin(),as.end());
	return as;
}
int main(){
	VI now,as;
	int i,n;
	while(~scanf("%d",&n)){
		now.clear();
		now.resize(n+1);
		for(i=n;i>=0;i--)
		    scanf("%lf",&now[i]);
		as=solve(now,n);
		for(i=0;i<as.size();i++)
		    if(fabs(as[i])!=inf)
		    printf("%.7lf\n",as[i]);
	}
	return 0;
}


 

你可能感兴趣的:(数论)