hdu1071(抛物线弓形面积阿基米德算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1071
题意:给出抛物线的顶点和它与一直线的两交点,求他们围成的面积;
思路:
可以直接求出他们的方程式,再积分,这个方法就不说了;
偶然看见另一个解法,觉得蛮有意思的,就记一下好了。。
抛物线与直线为成的面积等于直线的平行线与抛物线的切点和该直线与抛物线两交点组成的三角形面积 s*4/3;(抛物线弓形面积公式等于:以割线为底,以平行于底的切线的切点为顶点的内接三角形的4/3,即:抛物线弓形面积=S+1/4*S+1/16*S+1/64*S+……=4/3*S; 本渣渣百度的,抛物线弓形面积阿基米德算法,自己不会证明);
设 y=a*x*x+b*x+c;代入已知的三个点坐标,用行列式解三元三次方程组解出a, b, c;
直线的斜率可以通过p2, p3两点求出, k=(y3-y2)/(x3-x2);
对y=a*x*x+b*x+c求导得:y*=2*a*x+b=k;
可以解出x,反代入抛物线方程式中求出y;
现在我们已经求出了切点p(x, y),接下来还需要求一下三角形面积pp2p3面积s;
已知三点求三角形面积我们可以通过构造梯形再减去两个直角三角形面积得到;
推导初的面积公式为:s=(x*y2+y*x3+x2*y3-x*y3-y*x2-y2*x3)/2;
代码:
1 #include <iostream>
2 #include <stdio.h>
3 #include <math.h>
4 #define PI 3.1415926
5 #define INF 10000
6 using namespace std;
7
8 double matrix(int n, double a[3][3]){ //***3*3行列式计算
9 double sum1=a[0][0]*a[1][1]*a[2][2]+a[0][1]*a[1][2]*a[2][0]+a[1][0]*a[2][1]*a[0][2];
10 double sum2=a[2][0]*a[1][1]*a[0][2]+a[0][0]*a[2][1]*a[1][2]+a[2][2]*a[0][1]*a[1][0];
11 return sum1-sum2;
12 }
13
14 int main(void){
15 int t;
16 scanf("%d", &t);
17 while(t--){
18 double x1, y1, x2, y2, x3, y3;
19 scanf("%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3);
20 double matrix1[3][3]={y1, x1, 1, y2, x2, 1, y3, x3, 1};
21 double matrix2[3][3]={x1*x1, y1, 1, x2*x2, y2, 1, x3*x3, y3, 1};
22 double matrix3[3][3]={x1*x1, x1, y1, x2*x2, x2, y2, x3*x3, x3, y3};
23 double matrix4[3][3]={x1*x1, x1, 1, x2*x2, x2, 1, x3*x3, x3, 1};
24 double a=matrix(3, matrix1);
25 double b=matrix(3, matrix2);
26 double c=matrix(3, matrix3);
27 double d=matrix(3, matrix4);
28 a/=d;
29 b/=d;
30 c/=d;
31 double k=(y3-y2)/(x3-x2);
32 double x=(k-b)/(2*a);
33 double y=a*x*x+b*x+c;
34 double cnt=(x*y2+y*x3+x2*y3-x*y3-y*x2-y2*x3)/2;
35 printf("%.2lf\n", cnt*4/3);
36 }
37 return 0;
38 }