洛谷 1024一元三次方程

该博客讨论了NOIP的一道联赛题,涉及一元三次方程f(x)=ax^3+bx^2+cx+d=0的解法。题目要求找到在-100到100范围内差至少为1的三个实数根。文章对比了两种解题策略:一是采用二分法针对每个相隔1的区间搜索,二是通过切片枚举并二分查找。作者对自己的方法持保留态度,虽给出了代码,但不确定其正确性。

一道NOIP上古时代的联赛题,题目描述(我翻译的精简版…):
存在方程 f(x)=ax^3+bsquare(x)+cx+d=0, 已知有三个实数根在范围-100与100之内,解与解的差至少为1,请你求出这三个实数解,精确到小数点后2位。

先给出洛谷很多同学的标准解法:因为解与解的差至少为1,那么我们应该对于-100到100内所有为1的区间进行二分答案,直到我们找到三个解为止。

我的做法:对于-100 到 100这个区间进行切片,枚举切片的位置,那么必然存在三个区间包含了三个答案,对这三个区间进行二分,直到找到三个答案为止。

感觉自己这个做法很冒险,不清楚是否正确性充分,但是还是给出参考代码

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
double a, b, c, d;
double ans[505];
int cnt;
double pow(double x, int ex)
{
 int i;
 double ret=1;
 for(i=1;i<=ex;i++)
 {
  ret*=x;
 }
 return ret;
}
double func(double x)
{
 return a*pow(x,3)+b*pow(x,2)+c*x+d;
}
double bsearch(double left,double right)
{
 if(func(left)*func(right)>0)
  return 99999;
 if(func(left)==0&&func(right)!=0)
 {
  return left;
 }
 if(func(right)==0&&func(left)!=0)
 {
  return right;
 }
 if(func(right)==0&&func(left)==0)
 {
  return left;
 }
 if(left>right-0.001)
 {
  return (left+right)/2;
 }
 double mid = (left+right)/2;
 return min(bsearch(left,mid),bsearch(mid,right));
}
int main()
{
 int i, j, k;
 cin>>a>>b>>c>>d;
 double y1, y2, y3;
/* for(i=1;i<=3;i++)
 {
  if(i==1)
  {
   y1=bsearch(-100,100);
  }
  if(i==2)
  {
   y2=bsearch(y1+1,100);
  }
  if(i==3)
  {
   y3=bsearch(y2+1,100);
  }
 }
 cout<<y1<<' '<<y2<<' '<<y3<<endl;*/
 for(i=-99;i<=99;i++)
 {
  for(j=i+1;j<=100;j++)
  {
   double y1 = bsearch(-100,i);
   double y2 = bsearch(y1+1,j);
   double y3 = bsearch(y2+1,100);
   if(y1!=99999&&y2!=99999&&y3!=99999)
   {
    printf("%.2lf %.2lf %.2lf",y1,y2,y3);
    return 0;
   }
  }
 }
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值