noip2001一元三次方程求解(二分)

来源:互联网 发布:食品安全溯源软件下载 编辑:程序博客网 时间:2024/06/05 23:22

题目描述 Description

有形如:ax3+bx2+cx+d=0  这样的一个一元三次方程。给出该方程中各项的系数(abcd  均为实数),并约定该方程存在三个不同实根(根的范围在-100100之间),且根与根之差的绝对值>=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。
提示:记方程
f(x)=0,若存在2个数x1x2,且x1<x2f(x1)*f(x2)<0,则在(x1x2)之间一定有一个 根。

输入描述 Input Description

一个三次方程的各项系数

输出描述 Output Description

三个解

样例输入 Sample Input

1   -5   -4   20

样例输出 Sample Output

-2.00   2.00   5.00

数据范围及提示 Data Size & Hint
这题核心就是个二分答案,然而我这个脑残二分打错了(orz)

二分是while循环不是if(Qrz)

个人写成了二分套二分

对于枚举的区间[l,r],步长为1即r=l+1

如果 f(l)*f(r)<0 说明有一个解在这个区间内二分答案

如果f(l)*f(r)>0 说明没有解在这个区间内去查找下一个区间[r,r+1]

如果f(l)*f(r)=0 说明l是解或者r是解,就看哪个f=0 了

由于考虑到精度问题,都用1e-4即0.0001代替0

var        t               :longint;        i               :longint;        x1,x2,a,b,c,d   :double;        ans             :array[0..5] of double;function f(x:real):real;begin   exit(a*x*x*x+b*x*x+c*x+d);end;function find(l,r:double):double;var        mid:double;begin   mid:=(l+r)/2;   while (r-l>=1e-4) do    begin     if f(mid)=0 then exit(mid);     if (f(mid)*f(r)<0) then l:=mid+1e-4 else r:=mid-1e-4;     mid:=(l+r)/2;   end;   exit(mid);end;begin   read(a,b,c,d);   x1:=-100;x2:=x1+1;   while (t<3) and (x2<=100) do   begin      while (t<3) and (f(x1)*f(x2)>1e-4) do      begin         x1:=x2;         x2:=x1+1;      end;      //      while (t<3) and ((f(x1)*f(x2)<1e-4) and (f(x1)*f(x2)>-1e-4)) do      begin         inc(t);         if (f(x1)<1e-4) and (f(x1)>-1e-4) then         begin            ans[t]:=x1;            x1:=x2;            x2:=x1+1;         end else         begin            ans[t]:=x2;            x1:=x2+1;            x2:=x1+1;         end;      end;      //      while (t<3) and (f(x1)*f(x2)<-1e-4) do      begin         inc(t);         ans[t]:=find(x1,x2);         x1:=x2;         x2:=x1+1;      end;   end;   for i:=1 to 3 do write(ans[i]:0:2,' ');writeln;end.
——by Eirlys

转载请注明出处=w=


0 0
原创粉丝点击