題目鏈接: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 }