永发信息网

合并果子问题pascal

答案:4  悬赏:50  手机版
解决时间 2021-08-18 08:06
  • 提问者网友:轮囘Li巡影
  • 2021-08-17 09:19

我的想法是:从小到大排序 加合前面2个,不断循环

但是和答案差一点 谁帮我看看..

type
        int=longint;
var
        n,s,i,k,last:int;
        ai:array[1..20000]of int;

procedure qsort(l,r:int);
var
        i,j,mid,k:int;
begin
        i:=l; j:=r; mid:=ai[random(r-l)+l];
        repeat
                while ai[i]<mid do inc(i);
                while ai[j]>mid do dec(j);
                if i<=j then
                begin
                        k:=ai[i];
    ai[i]:=ai[j];
   ai[j]:=k;
                        inc(i); dec(j);
                end;
        until i>j;
 if i<r then qsort(i,r);
        if j>l then qsort(l,j);
end;

begin
        assign(input,'p1066.in');reset(input);
        assign(output,'p1066.out');rewrite(output);
        readln(n);
        for i:=1 to n do
        read(ai[i]);
        last:=n;

        for i:=1 to n do
        begin
                qsort(1,last);
                ai[2]:=ai[1]+ai[2];
                ai[1]:=0;
                k:=ai[last];
                ai[last]:=ai[1];
                ai[1]:=k;
                dec(last);
                s:=s+ai[2];
        end;

        writeln(s);
        close(input);close(output);
end.

最佳答案
  • 五星知识达人网友:独钓一江月
  • 2021-08-17 10:41

你每次都快排,时间复杂度太高,会超时。


不过你的思路是对的,但要用堆排来实现。


var
 x,y,i,j,k,m,n,t:longint;ans:int64;
 a:array[1..20000]of longint;


procedure work(i,n:longint);
var j,t:longint;
begin
 j:=i*2;
 while j<=n do
  begin
   if (j<n)and(a[j]>a[j+1]) then j:=j+1;
   if a[j]<a[i] then
    begin
    t:=a[i];a[i]:=a[j];a[j]:=t;
    i:=j;j:=i*2;
    end else exit;
  end;
end;


begin
 readln(n);m:=n;
 for i:=1 to n do read(a[i]);
 for i:= (n div 2) downto 1 do work(i,n);


 for k:=1 to n-1 do
  begin
   x:=a[1];a[1]:=a[m]; work(1,m-1);dec(m);
   y:=a[1];a[1]:=x+y;  work(1,m);
   ans:=x+y+ans;
  end;


 writeln(ans);
end.

全部回答
  • 1楼网友:神也偏爱
  • 2021-08-17 13:08

你的想法不错,但方法不行。

第一次用快排,以后用插排,不能用快排,不用堆排都可以。

具体程序如下算法:

var   a:array[0..15000] of longint;   i,j,n,k,tem,ans:longint; procedure sort(l,r:longint); var   i,j,x,y: longint; begin   i:=l;   j:=r;   x:=a[(l+r) div 2];   repeat     while a[i]<x do     i:=i+1;     while x<a[j] do     j:=j-1;     if not(i>j) then     begin     y:=a[i];     a[i]:=a[j];     a[j]:=y;     inc(i);     j:=j-1;     end;   until i>j;   if l<j then     sort(l,j);   if i<r then     sort(i,r); end; begin   assign(input,'T4.in');reset(input);   assign(output,'T4.out');rewrite(output);   readln(n);   for i:=1 to n do read(a[i]);   sort(1,n);   ans:=0;   i:=1;   while i<n do   begin     tem:=a[i]+a[i+1];     ans:=ans+tem;     j:=n;     while a[j]>tem do j:=j-1;     for k:=i to j do     a[k-1]:=a[k];     a[j]:=tem;     i:=i+1;   end;   writeln(ans);   close(input);close(output); end.

  • 2楼网友:琴狂剑也妄
  • 2021-08-17 12:10

tyvj的题目吧,大概是超时了吧,只能过几个点。你每次都快排,时间复杂度太高,每次改变的量都是ai[2],ai[1],不如把ai[2]插入,不过整个要动一动。每次去除ai[i],使ai[i+1]:=a[i+1]+a[i];从ai[i+2]向后搜,找到ai[i+1]的新位置,插入,其余前移一位,这样可以节约不少时间,当然用链表来做插入更方便

  • 3楼网友:孤老序
  • 2021-08-17 11:43
预处理时用快速排序,然后用堆做
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯