题目连接:~( ̄▽ ̄~)(~ ̄▽ ̄)~
用堆排序建立小根堆每回选取2个最小的值相加,再把得到的值放回堆中排序
code:
#include <stdio.h>
int num[20009], n = 0;
__int64 sum = 0, sum2 = 0;
void sift(int l);
void heapsort();
int main()
{
int i = 0;
while(scanf("%d",&n) != EOF)
{
sum = sum2 = 0;
for(i = 1; i<=n; i++)
scanf("%d",&num[i]);
heapsort();
printf("%I64d\n",sum2);
}
return 0;
}
void sift(int l)
{
int i = 0, j = 0, x = 0;
x = num[l];
i = l; j = 2*i;
while(j<=n)
{
if(num[j]>num[j+1] && j<n) j++;
if(x>num[j])
{
num[i] = num[j];
i = j;
j = 2*j;
}
else
break;
}
num[i] = x;
}
void heapsort()//堆排序
{
int i = n;
for(i = n/2; i>0; i--)
sift(i);//从底层向上对每个节点建立小根堆
while(n>=2)
{
sum = num[1];
num[1] = num[n];
n--;
sift(1);
sum += num[1];//用sum记录两最小元素的和
num[1] = sum;
sift(1);//把得到的和在入堆进行排序
sum2 += sum;//sum2记录当前2最小元素的和(即为要花的钱)
}
}