UVa10428 The Roots 题解
题目大意
给出一个
题目思路
这是牛顿迭代的一个标准的板子。
我们观测一下某个多项式
它现在的切线是这样的:
因而,我们可以把
可以看到它的切线再不断趋近于根,因此我们可以先把它的数学式写出来:设有一个函数
而后,我们可以先简单的化简一下:
我们当然不知道
最后,我们找到了一个根
这里多项式除法的具体细节略,但可以在代码中找到。代码如下。
#include <bits/stdc++.h>
using namespace std;
double EPS=1e-6;
int n;
double f[10],f_[10],g[10],g_[10],z[10];
double fc(double x){
double ans=0;
for(int i=n;i>=0;--i) ans=ans*x+f[i];
return ans;
}
double f_c(double x){
double ans=0;
for(int i=n-1;i>=0;--i) ans=ans*x+f_[i];
return ans;
}
double newton(double z){
while(fabs(fc(z))>=EPS) z-=fc(z)/f_c(z);
for(int i=n-1;i>=0;--i) g[i]=f[i+1]*z,f[i]+=f[i+1]*z;
for(int i=0;i<=n-1;++i) f[i]=g[i];
--n;
for(int i=n-1;i>=0;--i) f_[i]=f[i+1]*double(i+1);
return z;
}
int main(){
int _=0;
while(cin>>n&&n!=0){
int m=n;
for(int i=n;i>=0;--i) cin>>f[i];
for(int i=n-1;i>=0;--i) f_[i]=f[i+1]*double(i+1);
cout<<"Equation "<<(++_)<<": ";
for(int i=1;i<=m;i++) z[i]=newton(0);
sort(z+1,z+m+1);
for(int i=1;i<=m;i++) cout<<fixed<<setprecision(4)<<z[i]<<(i==m?'\n':' ');
cout<<flush;
}
return 0;
}
EOF