原题: http://acm.hdu.edu.cn/showproblem.php?pid=6487
题意:
有一个底面积S,高为H的桶,里面有V升水。现在有n个立方体,给出变长和密度,每个立方体不叠放,问水的高度。
解析:
假设二分到的水位为h,对于这个水位,求出当前的水的体积。若体积大于V则说明枚举过大。
证明:
对于一个大于答案水位的h,对于那些完全沉下去的和已经浮起来不用考虑。考虑加了水后浮起来的立方体,由于水的密度大于其密度,排开水的重量大于其重量,所以排开水的体积小于其体积。就会造成水体积的变大。
而那么完全沉下去和已经浮起来的占有体积不变,h偏大时也会导致水的体积变大,所以二分正确。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn=1e4+5;
double l[maxn],p[maxn],s,h,v;
int n;
bool check(double h){
double sum=h*s;
for(int i=1;i<=n;i++){
if(p[i]>=1){
sum-=l[i]*l[i]*min(l[i],h);
}
else{
if(l[i]*l[i]*l[i]*p[i]>l[i]*l[i]*h)sum-=l[i]*l[i]*min(l[i],h);
else sum-=l[i]*l[i]*l[i]*p[i];
}
}
if(sum>=v)return 1;
return 0;
}
int main(){
int t;scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf%lf",l+i,p+i);
}
scanf("%lf%lf%lf",&s,&h,&v);
double l=0,r=h;
while(r-l>0.0001){
double mid=(r+l)/2;
if(check(mid))r=mid;
else l=mid;
}
printf("%.2f\n",r);
}
}