3603 - 合并石子
Time Limit : 1 秒
Memory Limit : 128 MB
小Ray在河边玩耍,无意中发现一些很漂亮的石子堆,于是他决定把这些石子搬回家。河滩上一共有n(1≤n≤30000)堆石子,每次小Ray合并两个石子数最少的两堆石子成为一堆。经过n-1次合并操作以后,只剩下一堆石子,然后小Ray就将这一堆石子搬回家。每合并两堆石子的时候,小Ray消耗的体力是两堆石子的数量之和。请你算一算,小Ray合并所有石子堆消耗的体力是多少呢。
Input
第一行输入n,表示n堆石子。
第二行输入n堆石子的数量。
Output
输出一行表示消耗的体力。
Examples
Input Format
5 1 2 3 4 5
Output Format
33
Solution C
#include<stdio.h> int main(){ int x[30005],b[30005]={0},i,j,n,m1,m2,j1,j2,sum=0; scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&x[i]); for(j=1;j<n;j++){ m1=m2=1000000000;j1=j2=0; for(i=0;i<n;i++) if(b[i]==1)continue; else if(x[i]<m1) { if(x[i]<m2){m1=m2;j1=j2;m2=x[i];j2=i;} else{m1=x[i];j1=i;} } x[j2]=x[j1]+x[j2]; sum+=x[j2]; b[j1]=1; } printf("%d\n",sum); return 0; }
Solution C++
#include<cstdio> #include<iostream> #include<cstring> #include<queue> using namespace std; priority_queue <int> que; int main() { int n; scanf("%d",&n); for(int i=0,x;i<n;++i) { scanf("%d",&x); que.push(-x); } int ans=0; for(int i=1,tmp;i<n;++i) { tmp=que.top(); ans-=que.top(); que.pop(); tmp+=que.top(); ans-=que.top(); que.pop(); que.push(tmp); } cout<<ans<<endl; return 0; }