FZU - 1576【计算几何/费马点】

Oaiei居住在A城市,并且是这个城市建设的总设计师。最近有个问题一直困恼着他。A城市里有三个大型工厂,每个大型工厂每天都需要消耗大量的石油,现在城市里要建设一个石油中转站,从石油中转站到三个大型工厂都需要铺设石油管道。现在你的问题来了,应该如何建设这个石油中转站,使得石油中转站到三个大型工厂所需要铺设的石油管道线路最短,你能够帮助他吗?

设石油中转站B的坐标为(X,Y),三个大型工厂的坐标分别为C(X1,Y1),D(X2,Y2),E(X3,Y3),所输要铺设的石油管道线路总长为distance(B,C)+distance(B,D)+distance(B,E),其中distance(A,B)表示A,B两点之间的欧几里德距离。

Input

第一行为一个整数C(1<=C<=200),表示测试数据的组数。
以下C行,每行6个整数,分别表示C、D、E点 (X,Y)的坐标。注意:B点的选址可以与C、D、E点相重合。

Output

对于每个输入数据,输出一行两个数M1,M2,中间用一个空格分隔开。M1,M2分别四舍五入到小数点后两位,表示石油中转站的坐标。

Sample Input

1
0.00 0.00 1.00 0.00 0.00 1.00

Sample Output

0.21 0.21 

【模板】:http://blog.csdn.net/dingyaguang117/article/details/7216479

1.在一个三角形中,到3个顶点距离之和最小的点叫做这个三角形的费马点。

2.费马点计算方法:

(1)若三角形ABC的3个内角均小于120°,那么3条距离连线正好平分费马点所在的周角。所以三角形的费马点也称为三角形的等角中心。

(2)若三角形有一内角不小于120度,则此钝角的顶点就是距离和最小的点。 

3.如何计算等角中心呢?

做任意一条边的外接等边三角形,得到另一点,将此点与此边在三角形中对应的点相连

如此再取另一边作同样的连线,相交点即费马点

证明画几条辅助线就出来了~这里就不证明了

【代码】:
#include <iostream>
#include <math.h>
#include <windows.h>
#include <iomanip>
using namespace std;

struct Vec
{
    double x,y;
    Vec(double xx=0,double yy=0)
    {
        x=xx;
        y=yy;
    }
};

struct Point
{
    double x,y;
    Point(double xx=0,double yy=0)
    {
        x=xx;
        y=yy;
    }
};

double ddot(Vec A,Vec B)
{
    return A.x*B.x+A.y*B.y;
}
double getlen(Vec A)
{
    return sqrt(A.x*A.x+A.y*A.y);
}

double getlen(Point A,Point B)
{
    return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

bool moreThan120(double xa,double ya,double xb,double yb,double xc,double yc)
{
    Vec ab(xb-xa,yb-ya),ac(xc-xa,yc-ya);
    if (ddot(ab,ac)/getlen(ab)/getlen(ac) < -0.5)
    {
        return true;
    }
    return false;
}

inline void swap(double &a,double &b)
{
    double t;
    t=a;
    a=b;
    b=t;
}

Point getAnotherPoint(Point A,Point B,Point C)
{
    Point r,C1,C2;
    Vec AB(B.x-A.x,B.y-A.y);
    double len,len2;
    double sqrt3=sqrt(3.0);
    Vec AB2,crossAB,crossAB2;

    AB2.x=AB.x/2; AB2.y=AB.y/2;
    crossAB.x=AB2.y; crossAB.y=-AB2.x;
    crossAB2.x=-AB2.y; crossAB2.y=AB2.x;

    len=getlen(AB2);

    crossAB.x*=sqrt3; crossAB.y*=sqrt3;
    crossAB2.x*=sqrt3; crossAB2.y*=sqrt3;

    C1.x=A.x+AB2.x+crossAB.x;C1.y=A.y+AB2.y+crossAB.y;
    C2.x=A.x+AB2.x+crossAB2.x;C2.y=A.y+AB2.y+crossAB2.y;

    if (getlen(C,C1)<getlen(C,C2))
    {
        return C2;
    }else
        return C1;

}

/*
在平面内的两条直线AB,CD,求交点最直接的方法就是解下列的二元二次方程组:
Ax + (Bx - Ax)i = Cx + (Dx - Cx) j
Ay + (By - Ay)i = Cy + (Dy - Cy) j
交点是:
(Ax + (Bx - Ax) i, Ay + (By - Ay) i)
即:
  Ax + (AAx)i = Bx + (BBx) j
  Ay + (AAy)i = By + (BBy) j
  交点是:
(Ax + (AAx)i, Ay + (AAy)i)
*/
Point getCrossPoint(Point A,Point A1,Point B,Point B1)
{
    Point r;
    Vec AA(A1.x-A.x,A1.y-A.y),BB(B1.x-B.x,B1.y-B.y);
    double i,j,tmp,tmp2;
    double Ax=A.x,Ay=A.y,AAx=AA.x,AAy=AA.y,Bx=B.x,By=B.y,BBx=BB.x,BBy=BB.y;

    if (AAx==0)
    {
        j=(Ax-Bx)/BBx;
        i=(By+BBy*j-Ay)/AAx;
    }else if (BBx==0)
    {
        i=(Bx-Ax)/AAx;
    }else if (AAy==0)
    {
        j=(Ay-By)/BBy;
        i=(Bx-Ax-BBx*j)/AAx;
    }else if (BBy==0)
    {
        i=(By-Ay)/AAy;
    }
    else
    {
        tmp=AAx;
        tmp2=AAy;
        Ax*=AAy;AAx*=AAy;Bx*=AAy;BBx*=AAy;
        Ay*=tmp;AAy*=tmp;By*=tmp;BBy*=tmp;
        j=((Ax-Ay)-(Bx-By))/(BBx-BBy);
        i=(Bx+BBx*j-Ax)/AAx;
    }

    r.x=(Ax+AAx*i)/tmp2;
    r.y=(Ay+AAy*i)/tmp;
    return r;
}

int main()
{
    //freopen("cul.in9","r",stdin);
    int t;
    cin>>t;
    while(t--)
    {
        double xa,ya,xb,yb,xc,yc;
    Point C1,A1,R;

    cin>>xa>>ya>>xb>>yb>>xc>>yc;
    cout.setf(ios::fixed);

    if (moreThan120(xa,ya,xb,yb,xc,yc))
    {
        cout<<setprecision(2)<<xa<<" "<<ya<<endl;
    }else if (moreThan120(xb,yb,xa,ya,xc,yc))
    {
        cout<<setprecision(2)<<xb<<" "<<yb<<endl;
    }else if (moreThan120(xc,yc,xa,ya,xb,yb))
    {
        cout<<setprecision(2)<<xc<<" "<<yc<<endl;
    }else
    {
        C1=getAnotherPoint(Point(xa,ya),Point(xb,yb),Point(xc,yc));
        A1=getAnotherPoint(Point(xc,yc),Point(xb,yb),Point(xa,ya));

        R=getCrossPoint(Point(xa,ya),A1,Point(xc,yc),C1);
        cout<<setprecision(2)<<R.x<<" "<<R.y<<endl;
    }
    }
    //Sleep(1000000);
}

  

时间: 2024-08-02 17:33:22

FZU - 1576【计算几何/费马点】的相关文章

HDU - 1576(费马小定理求逆元)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9278    Accepted Submission(s): 7452 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%99

POJ 2420 A Star not a Tree? (计算几何-费马点)

A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3435   Accepted: 1724 Description Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allow you

hdu 4704 Sum (整数和分解+快速幂+费马小定理降幂)

题意: 给n(1<n<),求(s1+s2+s3+...+sn)mod(1e9+7).其中si表示n由i个数相加而成的种数,如n=4,则s1=1,s2=3.                         (全题文末) 知识点: 整数n有种和分解方法. 费马小定理:p是质数,若p不能整除a,则 a^(p-1) ≡1(mod p).可利用费马小定理降素数幂. 当m为素数,(m必须是素数才能用费马小定理) a=2时.(a=2只是题中条件,a可以为其他值) mod m =  *      //  k=

HDU 1098 Ignatius&#39;s puzzle 费马小定理+扩展欧几里德算法

题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为x可以任意取 那么不能总是满足 65|x 那么必须是 65 | (5*x^12 + 13 * x^4 + ak) 那么就是说 x^12 / 13 + x^4 / 5 + ak / 65 正好是一个整数 假设能找到满足的a , 那么将 ak / 65 分进x^12 / 13 + x^4 / 5中得到

【Lucas定理/费马小定理/中国剩余定理/扩展欧几里得】[BZOJ 1951] 古代猪文

[Description] 求 [Solution] 容易得到, 所以,重点在怎么求 如果是p-1是个质数,我们可以用sqrt(n)的时间枚举所有d,用Lucas定理分别计算求和即可. 但是我们发现p-1=2*3*4679*35617,并不是一个质数,所以Lucas定理不能用了吗?并不,我们可以算出这个合式分别对2.3.4679.35617的模值,写出四个同余方程,再用孙子定理求解即可.注意特判g==p的情况,此时费马小定理不成立,ans=0. [Code] #include<cmath> #

poj1379+POJ2420+hdu3932(最短距离+费马点+模拟淬火算法)

Run Away Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5632   Accepted: 1729 Description One of the traps we will encounter in the Pyramid is located in the Large Room. A lot of small holes are drilled into the floor. They look complet

hdu 4549 (矩阵快速幂+费马小定理)

题意:已知F0=a,F1=b,Fn=Fn-1*Fn-2,给你a,b,n求Fn%1000000007的值 思路:我们试着写几组数 F0=a F1=b F2=a*b F3=a*b2 F4=a2*b3 F5=a3*b5 我们发现a,b的系数其实是斐波那契数列,我们只需用矩阵快速幂求出相应系数就行,但是 这个系数随着增长会特别大,这时我们需要利用费马小定理进行降幂处理 费马小定理 ap-1≡1(mod p) 代码: #include <iostream> #include <cmath>

hdu1098费马小定理

Ignatius's puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 9783    Accepted Submission(s): 6839 Problem Description Ignatius is poor at math,he falls across a puzzle problem,so he has no

数论学习之费马与欧拉

数论复习之费马与欧拉 QB_UDG  2016年11月8日10:16:18 1.费马小定理 Fermat Theory 如果 p是素数,且a与p互质,即gcd(a,p)=1   那么(a^p-1) ≡ 1 (mod p) 应用: 求乘法逆元   乘法逆元: (x*x')≡ 1 (mod p) 称x'为x模p的乘法逆元 (注意,一定要是余1) 逆元 :(b/a) (mod n) = (b * x) (mod n). x表示a的逆元.并且 a*x ≡ 1 (mod n)  注意:只有当a与n互质的时