HDU OJ 1071: The area

HDU OJ 1071: The area

序言:
刚自学了一个月的算法,算个小萌新吧(其实实在菜的一匹…)。考虑到很多知识点容易遗忘,就准备写些东西来记录一下学习过程。第一次写博客,今天先写个简单的练练手。

Problem Description:

Ignatius bought a land last week, but he didn’t know the area of the
land because the land is enclosed by a parabola and a straight line.
The picture below shows the area. Now given all the intersectant
points shows in the picture, can you tell Ignatius the area of the
land?

Note: The point P1 in the picture is the vertex of the parabola.
这里写图片描述

Input:

The input contains several test cases. The first line of the input is
a single integer T which is the number of test cases. T test cases
follow. Each test case contains three intersectant points which shows
in the picture, they are given in the order of P1, P2, P3. Each point
is described by two floating-point numbers X and Y(0.0<=X,Y<=1000.0).

Output

For each test case, you should output the area of the land, the result
should be rounded to 2 decimal places.

Sample Input:

2
5.000000 5.000000
0.000000 0.000000
10.000000 0.000000
10.000000 10.000000
1.000000 1.000000
14.000000 8.222222

Sample Output:

33.33
40.69

Hint
For float may be not accurate enough, please use double instead of float.

解题思路:
这道题目的题意很明确,就是求直线和抛物线所围的面积。输入会给定三个点P1, P2, P3,其中P1是抛物线的顶点,P2和P3是抛物线与直线的交点。我们知道,三点可以唯一确定一条抛物线,两点可以唯一确定一条直线。因此,三点给定之后,直线和抛物线亦给定。我们可以用定积分的知识求解之。值得注意的是,虽然题目规定P1, P2, P3处于第一象限,但我们也需要考察抛物线的开口方向,因为开头向上和开口向下的求解方式是有些不同的。

1.开口向下

这里写图片描述

对于开头向上的情况,红色阴影的面积等于抛物线于P2到P3的积分再减去下方梯形的面积。对于梯形面积

S=(P2.y+P3.y)(P3.xP2.x)2

对于抛物线部分,由于我们已知其顶点。方便起见,我们可以采用顶点式来表达抛物线的解析式,即
f(x)=A(xP1.x)2+P1.y

其中,A是待定参数,选择P2或者P3代入均可解出唯一A。由此,可以写出抛物线的定积分
P3.xP2.xf(x)dx=[A3(xP2.x)3+(P1.y)x]P3.xP2.x

2.开口向上

这里写图片描述

对于开口向下,很显然,此时如果按照开口向上的方法进行计算,会得到所求面积的相反数。因此,我们可以用取绝对值的方法将两种情况进行归并。

至此,解题思路都已经有了,其他都交给code吧。值得注意的一点是,在分析过程中一直默认P2.x < P3.x,因此在存储数据的时候记得做一个预处理。

C++代码:

#include <iostream>
#include <math.h>
using namespace std;
namespace {
    struct Point
    {
        double x, y;
    };
}
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        Point P1, P2, P3;
        cin >> P1.x >> P1.y >> P2.x >> P2.y >> P3.x >> P3.y;
        if (P2.x > P3.x)
        {
            Point temp = P2;
            P2 = P3;
            P3 = temp;
        }
        double TrapezoidArea = (P2.y + P3.y) * (P3.x - P2.x) / 2;
        double a = (P2.y - P1.y) / (P2.x - P1.x) / (P2.x - P1.x);
        double b = P1.x;
        double c = P1.y;

        double CurveArea = (a / 3 * pow(P3.x - b, 3) + c * P3.x) - (a / 3 * pow(P2.x - b, 3) + c * P2.x);
        printf("%.2lf\n", abs(CurveArea - TrapezoidArea));//绝对值
    }
    return 0;
}

好的,以上奉出自己的第一次博客之旅。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值