uva 10250 - The Other Two Trees

刚开始做这道题的时候  想到的是两点距离公式和点积为零解方程解出两个解但是写出来是一个二元二次方程   不会解。。。

于是换成直线方程来做   铁定能解出来       但是忘记考虑了一个问题如果k很大的话   那么就没法做了  会溢出啊

不明白为什么k很大会溢出的自己推一推公式就明白了   所以直线方程法也不能用

于是只剩最后一种方法了  向量旋转法   因为这种方法以前没用过所以我刚开始的时候没有用   但是到最后不得不用了      

其实向量旋转方法做是最简单的。。。。   

下面是直线方程法解的 结果溢出了 没法做啊  

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

struct Point
{
    double x,y;
    Point():x(0),y(0){};
}A,C;

typedef struct Point point;

double Dist(point p1,point p2)
{
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}

int main()
{
    while (scanf("%lf%lf%lf%lf",&A.x,&A.y,&C.x,&C.y)!=EOF)
    {
        point B,D,M;
        double dis,k,l_b;
        M.x = (A.x +C.x)/2;
        M.y = (A.y +B.y)/2;
        if(A.x == C.x || A.y ==C.y)
        {
            if(A.x == C.x)
            {
                dis = fabs(A.y-C.y)/2;
                D.x = B.x = M.x;
                D.y = M.x + dis;
                B.y = M.x - dis;
            }
            else
            {
                dis = fabs(A.x-C.x)/2;
                D.y = B.y = M.y;
                D.x = M.x + dis;
                B.x = M.x - dis;
            }
        }
        else
        {
            printf("M.x = %lf  M.y = %lf\n",M.x,M.y);
            k = (A.x-C.x)/(A.y-C.y);
            dis = Dist(A,C)/2.0;
            l_b = M.y - k*M.x;//截距   没考虑到k很大的时候会溢出   所以直线方程的方法不能用
            printf("k = %lf  dis = %lf  l_b = %lf\n",k,dis,l_b);
            double a = 1.0+k*k;
            double b = -(2.0*M.x-2.0*k*l_b+2.0*M.y*k);
            double c = M.x*M.x+b*b-2*M.y*l_b+M.y*M.y-dis*dis;
            double dirt = sqrt(b*b-4.0*a*c);
            printf("a = %lf  b = %lf  c = %lf\n  dirt = %lf\n",a,b,c,dirt);
            B.x = (dirt-b)/(2.0*a);
            B.y = k*B.x +l_b;
            D.x = (-b-dirt)/(2*a);
            D.y = k*D.x +l_b;
        }
        printf("%.10lf %.10lf %.10lf %.10lf\n",D.x,D.y,B.x,B.y);
    }
    return 0;
}

然后换成向量旋转果断AC啊 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define eps 1e-6
using namespace std;

struct Point
{
    double x,y;
    Point():x(0),y(0){};
}A,C;

typedef struct Point point;

int main()
{
    while (scanf("%lf%lf%lf%lf",&A.x,&A.y,&C.x,&C.y)!=EOF)
    {
        if(fabs(A.x-C.x)<eps&&fabs(A.y-C.y)<eps)
        {
            printf("Impossible.\n");
            continue;
        }
        point B,D,M;
        M.x = (A.x +C.x)/2;
        M.y = (A.y +C.y)/2;
        B.x = M.x - (C.y - M.y);
        B.y = M.y + (C.x - M.x);
        D.x = M.x - (A.y - M.y);
        D.y = M.y + (A.x - M.x);
        printf("%.10lf %.10lf %.10lf %.10lf\n",D.x,D.y,B.x,B.y);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值