貌似牛顿迭代快如闪电,吊打二分。
虽然二次函数可以直接求根公式,,,但是我只是想练练牛顿迭代。
(要是以后考数学的时候我能直接用这个程序求零点就爽了Hhhh)
#include<bits/stdc++.h> #define ll long long #define newton 100 using namespace std; double a,b,c; double x,y; inline bool zero(double k){ return k>-0.00000001&&k<0.00000001; } inline void solve(int t){ double k,d; //t==1时是求左零点,否则是右零点 if(t==1) x=-b/(2*a)-1; else x=-b/(2*a)+1; //迭代次数 int tmp=newton; while(tmp--){ //算出当前点的切线方程,a*x^2+b*x+c的在(x0,y0)处的斜率就是2*a*x0+b k=x*a*2+b,d=y-k*x; //求切线与x轴交点 x=-d/k; y=x*x*a+x*b+c; } } int main(){ scanf("%lf%lf%lf",&a,&b,&c); if(b*b-4*a*c<-0.00000001){ puts("-1"); return 0; } solve(1); if(zero(x)) x=0; if(zero(y)) y=0; printf("%.6lf %.6lf\n",x,y); if(!zero(b*b-4*a*c)){ solve(2); if(zero(x)) x=0; if(zero(y)) y=0; printf("%.6lf %.6lf\n",x,y); } return 0; }
然后这个是求A的k次方根的
#include<bits/stdc++.h> #define ll long long using namespace std; double a,b,c,d; double x,y,A; int k; inline void solve(){ x=1.00,y=1-A; int tmp=1000; while(tmp--){ printf("%lf %lf\n",x,y); //求一下导 b=(double)k*pow(x,k-1); //确定点和斜率就可以确定切线方程了 d=y-b*x; //然后就可以找到和x轴的交点了 x=-d/b; //再找到y=x^k上横坐标是x的点 y=pow(x,k)-A; } } int main(){ //求A的k次方根 scanf("%d%lf",&k,&A); solve(); printf("%.6lf\n",x); return 0; }