2001NOI分区联赛复赛的一道题目:
求方程a*x*x*x+b*x*x+c*x+d=0的根(-100~100区间内),要求输入a,b,c,d,输出方程的解(3个)。
提示:已知x1<x2,f(x)=a*x*x*x+b*x*x+c*x+d,如果f(x1)*f(x2)<0则x1,x2之间必有一根。这题其实是一道5分钟的小题目,穷举法可以轻松实现,但却不是最优解,完全有超时的可能。我当时的想法是分支定界,通过化简树形解结构带到迅速求解的目的。由于有提示,我先到了“二分法”求解(递归),程序如下:
program noi2001_1(input,output);
var a,b,c,d:real;
function f(x:integer);
begin
f:=a*x*x*x+b*x*x+c*x+d;
end;
procedure work(x,y:integer);
var n:integer;
begin
if f(x)=0 then write(x:4)
else if f(y)=0 then write(y:4)
else begin
n:=(x+y) div 2;
if f(x)*f(n)<0 then work(x,n);
if f(n)*f(y)<0 then work(n,y);
end;
end;
begin
readln(a,b,c,d);
work(-100,100);
end.
看似好像没有什么大问题,但是总会有丢解的情况。由于时间有限,我只得先用穷举法完成,将题目带回来考虑。希望得到高手指点。
求方程a*x*x*x+b*x*x+c*x+d=0的根(-100~100区间内),要求输入a,b,c,d,输出方程的解(3个)。
提示:已知x1<x2,f(x)=a*x*x*x+b*x*x+c*x+d,如果f(x1)*f(x2)<0则x1,x2之间必有一根。这题其实是一道5分钟的小题目,穷举法可以轻松实现,但却不是最优解,完全有超时的可能。我当时的想法是分支定界,通过化简树形解结构带到迅速求解的目的。由于有提示,我先到了“二分法”求解(递归),程序如下:
program noi2001_1(input,output);
var a,b,c,d:real;
function f(x:integer);
begin
f:=a*x*x*x+b*x*x+c*x+d;
end;
procedure work(x,y:integer);
var n:integer;
begin
if f(x)=0 then write(x:4)
else if f(y)=0 then write(y:4)
else begin
n:=(x+y) div 2;
if f(x)*f(n)<0 then work(x,n);
if f(n)*f(y)<0 then work(n,y);
end;
end;
begin
readln(a,b,c,d);
work(-100,100);
end.
看似好像没有什么大问题,但是总会有丢解的情况。由于时间有限,我只得先用穷举法完成,将题目带回来考虑。希望得到高手指点。
是初中组第三道吧!!
让我想想
今年的比赛好像又要开始了
这个程序决不是像你想象的那么简单!!!
像这样用二分法只适用于只有一个解的情况
而这道题有三个解,比较麻烦
去年比赛结束的讲座上对这道题有详细的讲解,我想我应该还能做出来