zoukankan      html  css  js  c++  java
  • 懒省事的小明(优先队列)

     

    懒省事的小明

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:3
     
    描述
          小明很想吃果子,正好果园果子熟了。在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。小明决定把所有的果子合成一堆。 因为小明比较懒,为了省力气,小明开始想点子了:
      每一次合并,小明可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。小明在合并果子时总共消耗的体力等于每次合并所耗体力之和。
      因为还要花大力气把这些果子搬回家,所以小明在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使小明耗费的体力最少,并输出这个最小的体力耗费值。
      例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以小明总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
     
    输入
    第一行输入整数N(0<N<=10)表示测试数据组数。接下来每组测试数据输入包括两行,第一行是一个整数n(1<=n<=12000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
    输出
    每组测试数据输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。
    样例输入
    1
    3 
    1 2 9
    样例输出
    15
    题解:两种方法:数太大了,一种longlong 另一种用的大数,测试数据太水了;数组写的都不想找错了;测试数据为1 1 1时答案是2竟然ac。。。。另外queue里面没有迭代器,queue并不是容器而是容器适配器
    代码longlong:
     1 #include<stdio.h> 
     2 #include<vector> 
     3 #include<queue> 
     4 using namespace std; 
     5 int main(){ 
     6 int N,n,apple; 
     7 long long sum1,sum2,sum; 
     8 scanf("%d",&N); 
     9 while(N--){priority_queue<int,vector<int>,greater<int> >manual;sum=0; 
    10 scanf("%d",&n); 
    11 while(n--){ 
    12 scanf("%d",&apple); 
    13 manual.push(apple);  
    14 }       
    15 while(!manual.empty()){
    16 sum1=manual.top();         
    17 manual.pop();           
    18 sum2=manual.top();          
    19 manual.pop();        
    20 sum+=sum1+sum2;  
    21 if(!manual.empty())manual.push(sum1+sum2); 
    22 //printf("%lld  %lld
    ",sum,sum1+sum2);    
    23 } 
    24 printf("%lld
    ",sum); 
    25 } 
    26 return 0; 
    27 }

    代码大数:

     1 #include<stdio.h>
     2 #include<vector>
     3 #include<queue>
     4 #include<string.h>
     5 #define MAX(x,y) x>y?x:y
     6 using namespace std;
     7 struct Node{
     8     char s[100];
     9 };
    10 bool operator < (Node a,Node b){
    11     if(strcmp(a.s,b.s)>=0)return true;
    12     else return false;
    13 }
    14 void bigsum(char *a,char *b,char *sum){
    15     int c[100],i,j,t,z[100],d[100],t1,t2;
    16     memset(c,0,sizeof(c));memset(z,0,sizeof(z));
    17     memset(d,0,sizeof(d));
    18     t1=strlen(a);
    19     t2=strlen(b);t=MAX(t1,t2);
    20     for(i=t1-1,j=0;i>=0;i--,j++)c[j]=a[i]-'0';
    21     for(i=t2-1,j=0;i>=0;i--,j++)d[j]=b[i]-'0';
    22     for(i=0;i<t;i++){
    23         z[i]=c[i]+d[i]+z[i];
    24         if(z[i]>9)z[i+1]++,z[i]-=10;
    25         if(z[t])t++;
    26     }
    27     for(i=t-1,j=0;i>=0;i--,j++)sum[j]=z[i]+'0';
    28     sum[j]='';
    29     //printf("%s %s
    ",a,b);
    30 }
    31 int main(){
    32     int N,n;
    33     Node sum,apple,sum1,sum2,sum3;
    34     scanf("%d",&N);
    35     while(N--){priority_queue<Node>manual;memset(sum.s,0,sizeof(sum.s));
    36         scanf("%d",&n);
    37         while(n--){
    38             scanf("%s",apple.s);
    39             manual.push(apple);
    40         }
    41         while(!manual.empty()){memset(sum1.s,0,sizeof(sum1.s));
    42         memset(sum2.s,0,sizeof(sum2.s));memset(sum3.s,0,sizeof(sum3.s));
    43             sum1=manual.top();
    44             manual.pop();
    45             sum2=manual.top();
    46             manual.pop();
    47             bigsum(sum1.s,sum2.s,sum3.s);
    48             if(!manual.empty())manual.push(sum3);
    49             bigsum(sum.s,sum3.s,sum.s);
    50             //printf("%s  %s
    ",sum.s,sum3.s);
    51         //    puts("");    
    52         }
    53         printf("%s
    ",sum.s);
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    【5.3】dict的子类
    【5.2】dict的常用方法
    【5.1】dict的abc继承关系
    【4.5】列表推导式、生成器表达式、字典推导式
    【4.4】bisect维护已排序序列
    【4.3】实现可切片的对象
    【4.2】Python序列中+、+=和extend的区别
    【4.1】Python中的序列分类
    【3.12】contextlib简化上下文管理器
    【3.11】Python中的with语句
  • 原文地址:https://www.cnblogs.com/handsomecui/p/4682779.html
Copyright © 2011-2022 走看看