#4140: TLE或者速度不快的来看下


cfjhzcb (cfjhzcb)


一年前做过,一年以后重编一次竟然慢了几十倍

这是我一年前的程序  (38ms)

program d221;
var
  n,i,l1,l2,r:integer;
  a,b:array[1..5000] of longint;
  x1,x2:longint;
  s:qword;

procedure qsort(l,r:integer);
  var
    i,j:integer;
  procedure swap(i,j:integer);
    var
      t:longint;
    begin
      t:=a[i];a[i]:=a[j];a[j]:=t;
    end;
  begin
    i:=l;j:=r;
    swap(l,random(r-l)+l);
    while i<j do
      begin
        while (i<j) and (a[i]<=a[j]) do j:=j-1;swap(i,j);
        while (i<j) and (a[i]<=a[j]) do i:=i+1;swap(i,j);
      end;
    if i-1>l then qsort(l,i-1);
    if j+1<r then qsort(j+1,r);
  end;

procedure getmin(var x:longint);
  begin
    if l1<=n then
      if l2<=r then
        if a[l1]<b[l2] then
          begin
            x:=a[l1];
            l1:=l1+1;
          end
        else
          begin
            x:=b[l2];
            l2:=l2+1;
          end
      else
        begin
          x:=a[l1];
          l1:=l1+1;
        end
    else
      begin
        x:=b[l2];
        l2:=l2+1;
      end;
  end;

begin
  readln(n);
  while n<>0 do
    begin
      for i:=1 to n do
        read(a[i]);
      qsort(1,n);
      l1:=1;l2:=1;r:=0;
      s:=0;
      for i:=1 to n-1 do
        begin
          getmin(x1);getmin(x2);
          r:=r+1;
          s:=s+x1+x2;
          b[r]:=x1+x2;
        end;
      writeln(s);
      readln(n);
    end;
end.

这题huffman树 没有疑问了

 想法是构建2个队

一个是原队,一个是求和后的数队

因为每次都是最小的和 所以第二个队一定是升序的 

我们只要 先用n*logn的快排 让第一队有序

就可以用两个指针分别指向两队的开头,然后每次选取最小的2个相加,和再放入第2队中

这样实际做huffman树的效率是O(n) 只是一开始的排序浪费了点时间。。。

今天我编了个弱智程序 竟然要1.3秒。。。交完才发现以前做过。。。

 

别copy程序啊 分享一下解法而已