洛谷-P1090-合并果子

[NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G - 洛谷


解题思路:

1.由题可知,一共有n个数,每次都从中挑选出两个数来 进行合并,形成一个新的数,然后加入到数字中,继 续挑选两个最小的数合并,直至最后变成一个数,如 果每次合并后都将这两个数删除,加入一个数,重新 排序,显然会超出时间,所以应该利用两个数组来同 时存放原本的数字和合并好的数字

2. 第一个数组进行排序后,比较小的数都在前面,所以 可以按顺序取,第一次取前两个数来进行合并,将合 并好的数字放入第二个数组中,并且不再考虑前两个 数,第二次合并将第二个数组的数字和第一个数组中 第三第四位置的数取出两个较小值依次进行上述操作

3. 可能会想到第二个数组中会有好几个数,判断是否要 排序,将最小的数置入最前面,其实数组1已经排好 序,数组2中的数是由数组1合并来的,所以无论如 何,数组2的最小数一定在头部

4. 关于如何划掉已经合并的数,可以利用书签法来定 位,书签的位置就是没有被划掉的数,此外还要记录 两个数组中分别的元素个数,并且分别用不同的书签 去往后延伸,根据大小选取最小的两个数,每次选出 来这两个数,要把他们的和依次放入数组2中


#include<bits/stdc++.h>
using namespace std;
int a[10005],b[10005];//a数组用来存放原始数字,b数组存放已经合并的数字 
int main()
{
    int n;
    memset(a,127,sizeof(a));//将两个数组初始化为很大的值,防止0被当成果子数合并 
    memset(b,127,sizeof(b));

    cin>>n;
    for(int i=1;i<=n;i++)//原始数据依次存入数组a 
    cin>>a[i];

    sort(a+1,a+n+1);//快速排序,从小到大 

    int i=1,j=1,num,temp=1,sum=0;//i和j分别用来做数组ab的书签,num存放每次合并的果子数 
    //temp用来当每次num存放到数组b的位置下标

    for(int k=1;k<n;k++) //n个数合并的话取n-1次即可,手动验算 
    {
        if(a[i]<b[j])//如果数组a的值小于b 
        {
            num=a[i];//第一个最小值是a[i] 
            i++;//书签往后移动 
        }
        else//否则,第一个最小的值就是b[j],书签往后移动 
        {
            num=b[j];
            j++;
        }
        if(a[i]<b[j])//取第二个最小值,同理 
        {
            num=num+a[i];
            i++;
        }
        else
        {
            num=num+b[j];
            j++;
        }

        b[temp]=num;//将合并好的数字放入数组b下标为temp的位置 
        temp++;//下标后移,便于下一次存储 
        sum=sum+num;//累加活力值 
    }

    cout<<sum;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值