HDU2199(求解高次方程)

本文介绍了解一元高次方程的多种方法,包括牛顿迭代法、二分法及一种通用方法。通过这些方法,可以在指定范围内寻找方程的实数解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

problem

Now,given the equation 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,can you find its solution between 0 and 100;
Now please try your lucky.

Input

The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has a real number Y (fabs(Y) <= 1e10);

Output

For each test case, you should just output one real number(accurate up to 4 decimal places),which is the solution of the equation,or “No solution!”,if there is no solution for the equation between 0 and 100.

Sample Input

2
100
-4

Sample Output

1.6152
No solution!

思路

解一元高次方程,解给定了1~100这样一个区间,且保证了最多只有一个解

可以二分或者牛顿迭代法 先找到一个范围

二分法可能写搓了 还判了增减


还有一种更通用的方法,就是直接用递归解高次方程
具体见https://blog.youkuaiyun.com/feynman1999/article/details/80138789
代码见下文

牛顿迭代法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int debug_num=0;
#define debug cout<<"debug "<<++debug_num<<" :"

double y;

double f(double x)
{
    return (8*x*x*x*x+7*x*x*x+2*x*x+3*x+6-y);
}

double dao(double x)
{
    return (32*x*x*x+21*x*x+4*x+3);
}

int main()
{
    //freopen("in.txt","r",stdin);
    //ios::sync_with_stdio(false);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf",&y);
        //from 0 and 100  two close
        //cout<<ans1<<' '<<ans2<<endl;
        int flag=0;
        for(double ans=0;ans<=100-0.5;ans=ans+0.5){
            if(f(ans)*f(ans+0.5)>=0) continue;
            double t=ans;
            for(int i=0;i<20;++i){
                t=t-f(t)/dao(t);
            }
            if(t>=0&&t<=100){
                printf("%.4lf\n",t);
                flag=1;
                break;
            }
        }
        if(!flag) printf("No solution!\n");
    }
    return 0;
}

二分法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int debug_num=0;
#define debug cout<<"debug "<<++debug_num<<" :"

const double eps=1e-6;

double y;

double f(double x)
{
    return (8*x*x*x*x+7*x*x*x+2*x*x+3*x+6-y);
}

int main()
{
    //freopen("in.txt","r",stdin);
    //ios::sync_with_stdio(false);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf",&y);
        //from 0 and 100  two close
        //cout<<ans1<<' '<<ans2<<endl;
        int flag=0;
        for(double ans=0;ans<=100-0.5;ans=ans+0.5){
            if(f(ans)*f(ans+0.5)>0) continue;
            //ÔÚans~ans+0.5Çø¼äÄÚ
            double l=ans-0.5,r=ans+0.5;
            if(r>l){//increse
                while(r-l>eps)
                {
                    double mid=(l+r)/2;
                    if(f(mid)>=0) r=mid;
                    else l=mid;
                }
            }
            else{//decrese
                while(l-r>eps)
                {
                    double mid=(l+r)/2;
                    if(f(mid)<=0) r=mid;
                    else l=mid;
                }
            }
            if(r>=0&&r<=100){
                printf("%.4lf\n",r);
                flag=1;
                break;
            }
        }
        if(!flag) printf("No solution!\n");
    }
    return 0;
}

通用方法(解高次方程)

#include<bits/stdc++.h>
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;i<coef.size();++i) s+=coef[i]*e,e*=x;
    return 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;i<n;++i) dcoef[i]=coef[i+1]*(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+1<droot.size();++i){
        double tmp=Find(coef,n,droot[i],droot[i+1]);
        if(tmp<inf) ret.push_back(tmp);
    }
    return ret;
}

vector <double > ans;

vector <double > coef;

int main()
{
    //freopen("in.txt","r",stdin);
    //ios::sync_with_stdio(false);
    int t;
    int n;
    //scanf("%d",&n);
    n=4;
//    for(int i=0;i<=n;++i){
//        double tp;
//        scanf("%lf",&tp);
//        coef.push_back(tp);
//    }

    cin>>t;
    while(t--){
        ans.clear();
        coef.clear();
        coef.push_back(8);
        coef.push_back(7);
        coef.push_back(2);
        coef.push_back(3);
        double tp;
        cin>>tp;
        coef.push_back(6-tp);
        reverse(coef.begin(),coef.end());//注意顺序看要不要逆序   coef[0]放的是x^0对应的系数
        ans=solve(coef,n);
        //sort(ans.begin(),ans.end());
        int flag=0;
        for(int i=0;i<ans.size();++i){
            if(sign(ans[i])==1&&sign(ans[i]-100)==-1) printf("%.4f\n",ans[i]),flag=1;
        }
        if(flag==0) cout<<"No solution!"<<endl;
        //coef.erase(coef.rbegin());
        //coef.erase(coef.end()-1);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值