洛谷 1024一元三次方程

水题一道 枚举+二分方法

因为题目已经说了根与根之间的绝对值相差大于1,因此可以枚举每一个长度为一的小区间,在这个小区间二分即可

有两点要注意的:

1.精度的控制,一开始WA是因为精度没设置好,想着直接用int time = 50;while(time--)循环 但是这样wa了 改成while(right-left)之后就过了

2.区间要设置成左闭右开或者右闭左开的(如果是左闭右开最后再判断一下100,右闭左开则一开始判断一下-100),这样做的目的是为了防止重复枚举区间的边际值。

其他好像也没有什么坑点了 上代码:

#include <iostream>
#include<algorithm>
#include<cmath>
#include<iomanip>
using namespace std;
int cnt = 0;
double ans[3];
double a,b,c,d;
double cal(double x)
{
    return a*x*x*x +b*x*x +c*x +d;
}
void Find(double left,double right)
{
    double temp1 = cal(left);
    double temp2 = cal(right);
    double mid = (left+right)/2;
    int time = 100;
    while(right-left>=0.001)
    {
        if(cal(mid) == 0)
        {
            ans[cnt++] = mid;
            return;
        }
        if(cal(left) *cal(mid) >0)
            left = mid;
        else right = mid;
        mid = (left+right)/2;
    }
    ans[cnt++] = mid;
}
void Solve()
{
    for(int i= -100,j = -99;i<=99;i++,j++)
    {
        if(cnt>3)return;//已经找到3个答案了
        double temp1 = cal(i),temp2 = cal(j);
        if(temp1 == 0)
        {
            ans[cnt++] = i;//左闭右开的区间
            cout<<i<<" "<<j<<endl;
        }
        else if(temp1*temp2 < 0)
            {
                cout<<i<<" " <<j<<endl;
                Find(i,j);

            }
    }
    if(cal(100) == 0 && cnt<3)ans[cnt++] = 100;
}
int main()
{
    while(cin>>a>>b>>c>>d)
    {
        cnt = 0;
        Solve();
        cout<<fixed<<setprecision(2)<<ans[0]<<" "<<ans[1]<<" "<<ans[2];//<<endl;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值