关闭

合并果子(堆写法)

标签: c
433人阅读 评论(0) 收藏 举报
分类:

题目大意:

一个小朋友从树上打下了几堆果子。要将所有果子合并成一堆。给出没堆果子的重量求最小力气

本题的思路是要将重量最小的先合并,也就是传说中的哈夫曼树!但本题的数据比较大。今天我们来看堆得写法:

# include<stdio.h>
# include<stdlib.h>
long long a[1000010];
int main(){
    long long sum=0,ans=0,n,i,h,r,j;//本题要用long long不然会答案错误
    scanf("%I64d",&n);
    for(i=1;i<=n;i++){
        scanf("%I64d",&a[i]);//将重量存入堆
         r=i;//上浮
        while(r>1&&a[r]<a[r/2]){ 
            h=a[r];
            a[r]=a[r/2];
            a[r/2]=h;
            r/=2;
        }
    }
    int len=n;
    for(i=1;i<n;i++){
        sum=a[1];//将当前最小的放到本次合并中
        a[1]=a[len];
        len--;
        r=1;//下沉
        while((r*2<=len&&a[r]>a[r*2])||(r*2+1<=len&&a[r]>a[r*2+1])){
            j=r*2;
            if(j+1<=len&&a[j]>a[j+1])j++;
            h=a[r];
            a[r]=a[j];
            a[j]=h;
            r=j;
        }
        sum+=a[1];//将第二小的加入本次合并中
        a[1]=a[len];
        len--;
        r=1;//下沉
        while((r*2<=len&&a[r]>a[r*2])||(r*2+1<=len&&a[r]>a[r*2+1])){
            j=r*2;
            if(j+1<=len&&a[j]>a[j+1])j++;
            h=a[r];
            a[r]=a[j];
            a[j]=h;
            r=j;
        }
        ans+=sum;//合并
        a[++len]=sum;
        r=len;//上浮
        while(r>1&&a[r]<a[r/2]){
            h=a[r];
            a[r]=a[r/2];
            a[r/2]=h;
            r/=2;
        }
    }
    printf("%I64d\n",ans);
}
2
2

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5852次
    • 积分:489
    • 等级:
    • 排名:千里之外
    • 原创:38篇
    • 转载:1篇
    • 译文:0篇
    • 评论:2条
    文章分类
    最新评论