题意描述:
给你一个矩形的长和宽,在矩形的四个角减去四个边长为x的小正方形,然后折成一个无盖的盒子,求盒子的最大和最小体积时的x的值。
算法分析:
根据题目列出方程:设体积为f(x),减去正方形边长为x,则:f(x) = x * (L - 2 * x) * (W - 2 * x);
首先我们知道
f(x)肯定是大于等于0的,所以最小体积的x只能是0,和长和宽最短值的一半。也就是x的取值范围肯定是(0,min(L,W)/2).
知道了最小值是0和宽/2 (假设宽是短的那一条)。那么只需要求最大值就行了。
对f(x)求导数得:12*x*x - 4*(L+W)*x + L*W,经过计算这个函数的delt,可知这个函数是开口向上的与x轴有两个交点的抛物线。导函数的图像f(x)'如下:
由上图可知f(x)最大值就是f(x)' = 0的解中的较小的一个值,其中红色的是L== W的情况,蓝色的是L != W的情况,但是根据实际情况我们只能取到较小的一个,因为x已经规定了范围
(0,min(L,W)/2)。
所以这道题目最终结果肯定会输出3个值,一个是
12*x*x - 4*(L+W)*x + L*W = 0的较小的解,一个是0,一个是L和W中较小的一个中的一半。
讲到这里这道题目已经完了,但是你可能会wa,因为uva卡的很严,double类型会损失一定的精度,为了补回来,我们需要在最后的记过上加上1e-9.但是我们平时做题目不需要这样,那是题目结果不严格。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
const double EPS = 1e-9;
int main()
{
double L,W;
while (scanf("%lf %lf", &L, &W) != EOF)
{
double a,b,c,x1,x2,delt;
a = 12.0;
b = -4.0 * (L + W);
c = L * W;
delt = b * b - 4 * a * c;
x1 = (-b - sqrt(delt)) / (2.0 * a);
//x2 = (-b + sqrt(delt)) / (2.0 * a);
x2 = L < W ? L : W;
printf("%.3lf 0.000 %.3lf\n", x1 + EPS, EPS + x2 / 2.0);
}
return 0;
}