题目链接:1070 结绳
思路
- 典型的哈夫曼树思路,每次从现有的绳子里挑两根最短的合并。
- 为了节省时间,不用浮点数运算,把整数扩大2的N次方倍进行运算。
- 为了节省时间,扩大和缩小整数使用左移和右移操作。
代码
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int N;
cin >> N;
int a[N];
for(int i=0;i<N;i++){
scanf("%d",&a[i]);
a[i] << N;//左移N位
}
sort(a,a+N);
//每次从现有的绳子里挑两根最短的合并
for(int i=0;i<N-1;i++){
a[i+1] = (a[i] + a[i+1])/2;
//如果这次结果大了,重新排序
if(i<N-2 && a[i+1]>a[i+2]) sort(a+i+1,a+N);
}
a[N-1] >> N;//右移N位恢复
printf("%d",a[N-1]);
return 0;
}