3306 - bucket
绝恋作为物理课代表,当然不只是会收发作业,他还总是帮老班解决问题。
一天,老班给他一个这样的问题:
有一个水桶,里面原来有一定量的水,然后我们把一些箱子扔到桶里。箱子全扔进去后,我们再在水桶顶部加一个平顶的盖子。这样,如果一些漂浮在水面上的箱子的顶部高于桶壁高度,它就会被再往水里压一点,上表面顶着盖子。
下图是一种可能的情况:

<br />
<span style="font-family:仿宋;">箱子全部扔进水桶后,桶里的水面高度是多少?<span></span></span>
<span style="font-family:仿宋;">我们做如下约定:<span></span></span>
<span style="font-family:仿宋;">·水的密度是<span>1.0</span></span>
<span style="font-family:仿宋;">·可以忽略空气的存在对整个过程的影响<span></span></span>
<span style="font-family:仿宋;">·所有箱子都能完全放进水桶。也就是说,箱子的高不会大于水桶边缘高度<span></span></span>
<span style="font-family:仿宋;">·水桶中任意两个箱子都不互相接触<span></span></span>
但是这个问题实在很棘手,所以请你帮忙解决。<br />
Input
第一行是三个实数,分别是桶底面积S(0 < S <= 1000),水桶高度H(0 < H <= 1000),以及水桶中原有水的体积V(0 < V <= S * H)。第二行是一个正整数N(0 < N <= 1000),为扔进水桶的箱子的数目。接下来N行,每行包含两个实数,描述了一个正方体箱子:箱子每一边的长度L(0 < L <= 1000),以及箱子的密度D(0 < D <= 10)。
Output
输出一个实数,即箱子全扔进水桶后,水面的高度。结果保留7位小数。
Examples
Input
10 100 500 1 1 0.5
Output
50.0500000
Solution C++
#include<cstdio> #include<cstring> #include<cstdio> using namespace std; #define Size 1010 int n; double tubarea,tubheight,watersize; double boxlenth[Size]={0},boxden[Size]={0},boxsize[Size]={0}; bool judge(double); int main() { scanf("%lf%lf%lf",&tubarea,&tubheight,&watersize); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lf%lf",&boxlenth[i],&boxden[i]); if(boxden[i]<=1) boxsize[i]=boxden[i]*boxlenth[i]; else boxsize[i]=boxlenth[i]; } double left=watersize/tubarea,right=tubheight,middle; while(right-left>1e-9) { middle=(left+right)/2; if(judge(middle)) right=middle; else left=middle; } printf("%.7lf",left); return 0; } bool judge(double waterheight) { double devote=0; for(int i=1;i<=n;i++) { if(boxsize[i]>waterheight) devote=devote+waterheight*boxlenth[i]*boxlenth[i]; else { if(waterheight+boxlenth[i]-boxsize[i]>tubheight) devote=devote+(boxlenth[i]-(tubheight-waterheight))*boxlenth[i]*boxlenth[i]; else devote=devote+boxsize[i]*boxlenth[i]*boxlenth[i]; } } if(devote<=(waterheight-watersize/tubarea)*tubarea) return true; else return false; }