http://poj.org/problem?id=1862
题目大意:
有一种生物能两两合并,合并之前的重量分别为m1和m2,合并之后变为2*sqrt(m1*m2),现在给定n个这样的生物,求合并成一个的最小重量
思路:
m1+m2 >= 2*sqrt(m1*m2)
所以每次取大的去合并,能变小。
直接优先队列就可以啦。
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
priority_queue<double> q;
int main()
{
int n;
while(~scanf("%d",&n))
{
double temp;
for(int i=0;i<n;i++)
{
scanf("%lf",&temp);
q.push(temp);
}
while(!q.empty())
{
double t1=q.top();
q.pop();
if(q.empty())
{
printf("%.3lf\n",t1);
break;
}
double t2=q.top();
q.pop();
double t3;
t3= 2 * sqrt(t1*t2);
q.push(t3);
}
}
return 0;
}
自己写的堆
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
const int MAXN = 128;
struct Heap
{
int curSize;
double data[MAXN];
Heap(){curSize =0;}
void push(double x)
{
int hole = ++curSize;
for(;hole > 1 && data[hole>>1] < x ;hole>>=1)
data[hole] = data[hole>>1];
data[hole] = x;
}
void pop()
{
data[1] = data[curSize--];
matain(1);
}
void matain(int hole)
{
double x = data[hole];
for(int child;(hole<<1) <= curSize;hole=child)
{
child = hole << 1;
if(child!=curSize && data[child] < data[child+1])
child++;
if( x > data[child] ) break;
data[hole]=data[child];
}
data[hole] = x;
}
double top(){return data[1];}
bool empty(){return curSize == 0;}
};
int main()
{
int n;
while(~scanf("%d",&n))
{
Heap q;
for(int i=0;i<n;i++){
int x;
scanf("%d",&x);
q.push(x);
}
while(!q.empty())
{
double x1 = q.top();q.pop();
if(q.empty()){
printf("%.3lf\n",x1);
break;
}
double x2=q.top();q.pop();
q.push(sqrt(x2*x1)*2);
}
}
return 0;
}