合并果子(Vijos P1097)

  刚刚做出这道题,感觉很兴奋啊,对于我这种弱菜来说能完美的AC这道题真是令人振奋不已啊!

  (情不自禁的将AC记录发上来了,勿怪勿怪!)

  这道题是我们向总点名要做的,这几天学了很多新内容,于是乎拖到了今天才做。

  由于刚刚学了堆排序,仔细一看这道题的描述,感觉用堆排序来做真是再合适不过了(网上貌似有很多做法,快排什么,有机会换个算法编一下),因为只需要将合并产生的数据放入堆中筛一遍即可。

  刚开始认为只不过是简单的将堆排序中将第一个置换为最后一个,并将dec(记录指针,2)就可以了。就这样随便整了一下就交上去了,发现只有10分(说到这个10分,某位大神还以为是哪个小地方出了问题,结果我一看测试数据,发现对的那个点就是题目给出的例子,蛋疼有木有???)。

  冥思苦想了好一会,终于想明白了不要一次性将第一第二两个值全换掉,这样堆筛下来无法得到正确的序列。先将最后一个置换为第一个,筛一遍,由于筛过后排在第一个的数据一定是刚刚第二小的数据,只需要用刚刚记录下来的x[1]+x[2]将其置换即可。

  务必记在在dec(指针)之前将当前指向的数据赋值为maxlongint,否则会造成严重后果,就是被这个卡了好久(因为数组很大,之后的数据全部为0,会造成将0置换上来的情况,置为maxlongint便不会出现这个问题)。

  废话不多说,直接上源代码:

 

 1 program duipaixu2;
 2 type
 3         arr=array[1..10001] of longint;
 4 var
 5         x:arr;
 6         i,j,j1,n:longint;
 7         bool:boolean;
 8         s,s1:int64;
 9 procedure heap(var x:arr;j,i:longint);【堆排序】
10 var
11         i2,t1:longint;
12 begin
13         t1:=x[i];
14         i2:=2*i;
15         while  i2<=j do
16         begin
17                 if (i2<=j) and (x[i2] > x[i2+1]) then i2:=i2+1;
18                 if t1 > x[i2] then
19                 begin
20                         x[i]:=x[i2];
21                         i:=i2;i2:=2*i;
22                 end
23                 else i2:=j+1;
24         end;
25         x[i]:=t1;
26 end;
27 {================== main =====================}
28 begin
29         assign(input,'hebin.in');
30         assign(output,'hebin.out');
31         reset(input);
32         rewrite(output);
33         read(n);
34         for i:=1 to n do
35                 read(x[i]);
36         x[n+1]:=maxlongint;
37         j:=n;
38         s:=0;
39         s1:=0;
40         for i:=n div 2 downto 1 do  【建立新堆】
41                         heap(x,n,i);
42         repeat
43                 bool:=true;
44                 if x[2]<=x[3] then
45                 begin
46                         s1:=x[1]+x[2];
47                         s:=s+s1;
48                 end
49                 else begin s1:=x[1]+x[3];s:=s+s1 end;
50                 j1:=j;
51                 dec(j);
52                 if j>1 then
53                 begin
54                         x[1]:=x[j1];
55                         x[j1]:=maxlongint; 【这一步很重要,否则会出现上文提到的结果】
56                         heap(x,j,1);    【分两次筛】
57                         x[1]:=s1;
58                         heap(x,j,1);
59                 end;
60         until j=1;
61         write(s);
62         close(input);
63         close(output);
64 end.

By ZYT

12.10.05

转载于:https://www.cnblogs.com/cszyt/archive/2012/10/05/2712452.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值