解方程(有点精度问题)

#include
#include
#include
using namespace std;
const int MaxN = 100 + 10;
const long double eps = 1e-16, INF = 1e20;
int n,sl[MaxN];long double f[MaxN][MaxN],ans[MaxN][MaxN],t;
int sgn(double x)
{
	if(x<0) return -1;
	if(x>0) return 1;
	return 0;
}
long double calc(int v,double x)
{
	long double t=1,ret=0;
	for(int i=0;i<=v;i++)
	{
		ret+=t*f[v][i];
		t*=x;
	}
	return ret;
}
bool erf(int v,long double st,long double en)
{
	if(sgn(calc(v,st))*sgn(calc(v,en))>0) return false;
	long double mid;bool kk=(sgn(calc(v,st))>=0);
	while(fabs(st-en)>eps)
	{
		mid=(st+en)/2.0;
		if(sgn(calc(v,mid))>=0)
		{
			if(kk) st=mid;
			else en=mid;
		}
		else
		{
			if(kk) en=mid;
			else st=mid;
		}
	}
	if(kk) t=st;
	else t=en;
	return true;
}
void ask(int v)
{
	if(v==1)
	{
		if( sgn(f[v][1]) )	ans[v][sl[v]=1]=-f[v][0]/f[v][1];
		else sl[v]=0;
		return;
	}
	for(int i=1;i<=v;i++) f[v-1][i-1]=f[v][i]*i;
	ask(v-1);
	ans[v-1][0]=-INF;ans[v-1][sl[v-1]+1]=INF;
	for(int i=0;i<=sl[v-1];i++)
		if(erf(v,ans[v-1][i]+eps,ans[v-1][i+1]))	ans[v][++sl[v]]=t;
}
int main()
{
	scanf("%d",&n);
	for(int i=n;i>=0;i--) cin>>f[n][i];
	ask(n);
	for(int i=1;i<=sl[n];i++) cout<

题目描述:

方程: a0 * x^n + a1 * x^(n-1) + a2 * x^(n-2) + ... + an = 0

求方程在 [-10^20,10^20] 内的实数解

输入:

第一行:一个整数n,表示最高项指数 n>=1

第二行:接下来n+1个实数数 分别表示 a0,a1,a2,a3...,an 

输出:

对于每一个解输出一行



想法(未证明):

对于 f(x) = a0 * x^n + a1 * x^(n-1) + a2 * x^(n-2) + ... + an = 0 求拐点,对于每一段单调区间进行二分

求拐点: 求f(x)导函数 f'(x) 则 变为求 f'(x)=0 (递归求解)

你可能感兴趣的:(算法)