最小函数值问题解决.doc
文本预览下载声明
【题目描述】有n个函数,分别为F1,F2,...,Fn。定义Fi(x)=Ai*x^2+Bi*x+Ci(xN*)。给定这些Ai、Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个【格式神马的】输入数据第一行输入两个正整数n(n=10000)和m(m=10000)。以下n行每行三个正整数,其中第i行的三个数分别位Ai、Bi和Ci。输入数据保证0Ai=10,0Bi=100,0Ci=10 000。
输出数据输出将这n个函数所有可以生成的函数值排序后的前m个元素。这m个数应该输出到一行,用空格隔开。
样例输入3 104 5 33 4 51 7 1
样例输出9 12 12 19 25 29 31 44 45 54【规模】20%的数据n=100100%的数据n=1000090%的数据9000=m=10000
【分析】利用堆结构,建大根堆,再用堆排序。建大根堆的过程中用到小根堆来取fi[x]中最小的数。堆满后,还要进行若干取最小数的过程,直到新的最小数比大根堆中根要大。若要输出前12个数,应为9 12 12 19 25 29 31 44 45 54 61 69。?
?program p3;
?
?var minh,maxh:array[1..10000]of longint;
???? a,b,c:array[1..10000]of integer;
????? te,n,m,i,j,lmin,lmax,x:longint;
?
?function f(i,x:integer):longint;
?begin
?? f:=a[i]*x*x+b[i]*x+c[i];
?end;
?procedure putmin(y:longint);//建立小根堆
?var te:longint;son:integer;
?begin
?? lmin:=lmin+1;
?? minh[lmin]:=y;
?? son:=lmin;
?? while (son1)and(minh[son div 2]minh[son]) do
?? begin
????? te:=minh[son];
????? minh[son]:=minh[son div 2];
????? minh[son div 2]:=te;
????? son:=son div 2;
?? end;
?
?end;
?procedure putmax(y:longint);//建立大根堆
?var te:longint;son:integer;
?begin
?? lmax:=lmax+1;
?? maxh[lmax]:=y;
?? son:=lmax;
?? while (son1)and(maxh[son div 2]maxh[son]) do
?? begin
????? te:=maxh[son];
????? maxh[son]:=maxh[son div 2];
????? maxh[son div 2]:=te;
????? son:=son div 2;
?? end;
?
?end;
?function getmin():longint;//取小根堆中根结点
?var fa,son:integer;te:longint;
?begin
?? getmin:=minh[1]; minh[1]:=minh[lmin];
?? lmin:=lmin-1;
?? fa:=1;
?? while (fa*2=lmin)or(fa*2+1=lmin) do
??begin
???? if(fa*2+1lmin)or (minh[fa*2]minh[fa*2+1]) then son:=fa*2
??????????????????????????????????????????????? else son:=fa*2+1;
???? if minh[fa]minh[son] then
???? begin
?????? te:=minh[fa];
?????? minh[fa]:=minh[son];
?????? minh[son]:=te;
?????? fa:=son;
???? end
???? else break;
?? end;
?end;
?procedure tiao(i:longint);//调整大根堆
?var i0,y0,j0:longint;
?begin
??? i0:=i;
??? y0:=maxh[i];
????j0:=2*i0;
??? while j0=lmax do
????begin
????? if(j0lmax)and(maxh[j0]maxh[j0+1]) then j0:=j0+1;
显示全部