解题思路:我们已知三个点分别是抛物线顶点,直线交于抛物线的两点。求出两条线的解析式然后用定积分公式就解决了。那么,难点来了,怎么求这个直线和抛物线的解析式呢?直线的解析式我们已知两点,用两点斜率公式求出斜率k,然后回待直线方程中求出与y轴的交点的纵坐标L,之后看看抛物线,因为知道顶点横坐标,即抛物线的对称轴,x1=-b/2*a,如果求出a,b之后我们就可以带入假设的抛物线坐标方程y=ax^2+bx+c中,就求出c。a怎么求呢?起初我是联立两条线的方程后作差,即:
/*
ax2^2+bx2+c=kx2+l ①
ax3^2+bx3+c=kx3+l ②
由①-②:
a(x2^2-x3^2)+b(x2-x3)=k(x2-x3)
==> a(x2+x3)(x2-x3)+b(x2-x3)=k(x2-x3)
==> (x2-x3)(a(x2+x3)+b)=k(x2-x3)
两边同时消去(x2-x3):
a(x2+x3)+b=k ③
又 x1=-b/(2a) ==> b=-2ax1 ④
由③,④得:
a=k/(x2+x3-2x1) (x2+x3!=2x1) ==>直线斜率不为0
*/
但是当直线斜率为0时分母就会为0,显然不成立。这时候怎么求这个a呢?后来想要用矩阵化成最简式,然后对应的a,b,c的解就能够得出来了,不过计算量好复杂,ps。后来看了别人求抛物线的方程才知道我一开始就偏了。既然知道顶点的坐标,直接设顶点式:y=a(x-x1)^2+y1,然后待如一点就求出a了,其实这里的a和y=ax^2+bx+c的a是等同的,所以直接改一下a的求法就AC了。a=(y2-y1)/((x2-x1)^2) !!
还有注意的点就是算式子的时候我下面代码求面积注释的那种写法不能用,可能乘完再除和除完乘的精度不一样使得答案不一样
AC代码如下:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
#include<queue>
#include<map>
#include<math.h>
using namespace std;
double S(double x1,double y1,double x2,double y2,double x3,double y3)
{
double k,l,a,b,c,s;
k=1.0*(y2-y3)/(x2-x3);
l=y2-k*x2;
//a=1.0*k/(x2+x3-2*x1); 当斜率为0时不成立
a=1.0*(y2-y1)/((x2-x1)*(x2-x1));
b=-2*a*x1;
c=y1-a*x1*x1-b*x1;
//s=1.0*x3*(x3*(a*x3/3.0+(b-k)/2.0)+c-l)-1.0*x2*(x2*(a*x2/3.0-(b-k)/2.0)+c-l);
s=(1.0*a*x3*x3*x3/3.0+(b-k)*x3*x3/2.0+(c-l)*x3)-(1.0*a*x2*x2*x2/3.0+(b-k)*x2*x2/2.0+(c-l)*x2);
return s;
}
int main()
{
double x1,y1,x2,y2,x3,y3,a,b,c,k,l,s;
int t;
cin>>t;
while(t--)
{
cin>>x1>>y1>>x2>>y2>>x3>>y3;
//y=k*x+l y=a*x^2+b*x+c
s=S(x1,y1,x2,y2,x3,y3);
printf("%.2lf\n",s);
}
return 0;
}
积分公式的东西就不说了