Viviani


输入描述:

依次给出等边三角形的3个顶点坐标A, B, C 和P点的二维几何坐标(x, y)(x,\, y)(x,y)。(0≤∣x∣, ∣y∣<10 0000 \leq |x|,\, |y| < 10 \, 0000x,y<10000 )

保证P点在等边三角形内,包括边。

 

输出描述:

如图,求P点到各边的距离和(s + t + u)。

只要你的答案与标准答案误差的绝对值在10−610^{-6}106以内都会算作正确。

链接:https://ac.nowcoder.com/acm/contest/2763/A


题解:给一个等边三角形和点p,p在三角形内,包括边,求p到三条边的和。
①特判p是否在某条边上,在的话该距离为0。计算p和A的斜率,a和B的斜率,如果斜率相等,p在AB上
②海伦公式:

, P=(a+b+c)/ 2;  p为周长的一半
把p和A、B当成一个三角形,先用海伦公式求面积,又知AB长度,所以可解得高,即为p到AB的距离
 
 
#include 
 
using namespace std;
 
double xp,yp;
 
double height(double x1, double y1, double x2, double y2){
    double k1= (y2-y1)/(x2-x1);
    double k2 = (yp-y2)/(xp-x2);
    if(k1 == k2)    return 0;           //p点在边上,返回0
    double d1=(x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
    d1=sqrt(d1);
    double d2=(x2-xp)*(x2-xp) + (y2-yp)*(y2-yp);
    d2=sqrt(d2);
    double d3=(x1-xp)*(x1-xp) + (y1-yp)*(y1-yp);
    d3=sqrt(d3);
    double p=(d1+d2+d3)/2;
    double s= sqrt(p*(p-d1)*(p-d2)*(p-d3));      //海伦公式
    double h = s*2/d1;
    return h;
}
 
int main(){
    double x1,y1,x2,y2,x3,y3;
    while(scanf("%lf %lf",&x1,&y1)!=EOF){
        scanf("%lf %lf",&x2,&y2);
        scanf("%lf %lf",&x3,&y3);
        scanf("%lf %lf",&xp,&yp);
        double d1=height(x1,y1,x2,y2);
        double d2=height(x1,y1,x3,y3);
        double d3=height(x2,y2,x3,y3);
        double sum=d1+d2+d3;
        printf("%.11lf\n",sum);    //输出11位小数
    }
    return 0;
}



PS:还有一种更精简的解法?? 但不理解这个思路
#include
#include
int main()
{
    double a[2],b[2],c[2],p[2];
    scanf("%lf%lf",&a[0],&a[1]);
    scanf("%lf%lf",&b[0],&b[1]);
    scanf("%lf%lf",&c[0],&c[1]);
    scanf("%lf%lf",&p[0],&p[1]);
    double ans;
    ans=(sqrt(3)*sqrt(pow(a[0]-b[0],2)+pow(a[1]-b[1],2)))/2;
    printf("%lf\n",ans);
    return 0;
 }

 

 

你可能感兴趣的:(Viviani)