双数组仿哈夫曼编码---合并果子新思路
#include <iostream> #include <algorithm> #include <cstring> using namespace std; int n,n2,a1[10010],a2[10010],sum=0; // n是种类 n2表示第二个篮子现在合并了多少种了 利用这个数来更新a2数组里面的元素 没更新之前都让他们最大就行了 按照题目的意思 只要达到2^32左右肯定是没问题的 所以联想到memset给个int极大值就行 // a1是第一个篮子 装有所有种类的果实的个数 开始时先排序一下 // a2是第二个篮子 用来装合并的果子的 // sum用来计算体力消耗量 每次合并完成之后 就应该消耗一些体力 顺势加入到sum里面 int main() { cin>>n; memset(a1,127,sizeof(a1));//将一个数组初始化为一个接近int最大值的数 变成最大值是为了在之后的值比较的时候没用过的数组的位置永远要比要来比较的来的大 // 与此同时该函数比for循环效率高很多 memset(a2,126,sizeof(a2));// 将第1,2数组都初始化为一个int最大值 for(int i=0;i<n;i++)// 输入果子 cin>>a1[i]; sort(a1,a1+n);// 仅做一次排序 对 第一个数组 int i=0,j=0,k; // i是第一个数组的书签位置,表示现在第一个数组里面的果子 要拿出来合并的到这里 一个标记位置 同理j是第二个数组的书签位置,表示现在合并到了这个位置 int w;// 先找一个最小值(按顺序找第一个数组和第二个数组的标签位进行比较) 再找下一个最小值 进行相加 得到一个合并的果子 // 并把这个果子合并出来的值 加到sum统计里面去 for(k=1;k<n;k++)// 最多只需要将这套动作做n-1次 { w=a1[i]<a2[j] ? a1[i++] : a2[j++];// 先拿出一个最小值来 必须比较两个篮子 因为合并之后的果子出来的质量和 也有可能比第一个篮子的轻 ,注意增加++ 每次书签位置都在使用了之后向前进1 w+=a1[i]<a2[j] ? a1[i++] : a2[j++];// 现在开始要看 下一个了,到底这一个是在第二个蓝子里面 还是在第一个篮子里面 需要将此事的i位置的a1元素 和j位置的a2元素拿出来进行比较 // 好了合并出来一个w了 // 现在n2登场,把合并的东西放到n2位置上 a2[n2++]=w;//n2就是此时已经合并出来的果子的个数 在这里更新一下a2 方便它在下次循环中进行比价 sum+=w;// 每次合并完成之后都把合并的果子算到消耗体力中去 } cout<<sum; return 0; }
希望与孩子们一起成长,见证