HDU3694 Fermat Point in Quadrangle(求四边形费马点)

题意:给个四边形,问一个点到四边形四个点距离最小的距离和是多少。

分析:如果是凸四边形,费马点就是对角线的交点,距离就是对角线长度。

如果是凹多边形,费马点就是那个凹点。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<algorithm>
#include<ctime>
using namespace std;
#define eps 1e-8
int Fabs(double d)
{
    if(fabs(d)<eps) return 0;
    else return d>0?1:-1;
}
struct point
{
    double x,y;
}p[10],sta[10];
int oper[8][2]={0,1,0,-1,-1,0,1,0,1,1,1,-1,-1,1,-1,-1},top;
double x_multi(point p1,point p2,point p3)
{
    return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
}

double Dis(point p1,point p2)
{
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
bool cmp(point a,point b)
{
    if(Fabs(x_multi(p[0],a,b))>0) return 1;
    if(Fabs(x_multi(p[0],a,b))<0) return 0;
    if(Fabs(Dis(p[0],a)-Dis(p[0],b))<0)
        return 1;
    return 0;
}
void Graham(int n)
{
    int i,k=0,tot;
    for(i=1;i<n;i++)
        if((p[i].y<p[k].y)||((p[i].y==p[k].y)&&(p[i].x<p[k].x)))
            k=i;
    swap(p[0],p[k]);
    sort(p+1,p+n,cmp);
    sta[0]=p[0],sta[1]=p[1];
    i=top=1;
    for(i=2;i<n;i++)
    {
        while(top>=1&&Fabs(x_multi(p[i],sta[top],sta[top-1]))>=0)
        {
            if(top==0) break;
            top--;
        }
        sta[++top]=p[i];
    }
}
int main()
{
    int i,j;
    while(~scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p[0].x,&p[0].y,&p[1].x,&p[1].y,&p[2].x,&p[2].y,&p[3].x,&p[3].y))
    {
        if(p[0].x==-1&&p[0].y==-1&&p[1].x==-1&&p[1].y==-1&&p[2].x==-1&&p[2].y==-1&&p[3].x==-1&&p[3].y==-1)
            break;
        Graham(4);
        double ans;
        if(top==3)
            ans=Dis(sta[0],sta[2])+Dis(sta[1],sta[3]);//凸四边形就直接取对角线交点
        else
        {
            ans=1e50;
            double sum=0;
            for(i=0;i<4;i++)
            {
                sum=0.0;
                for(j=0;j<4;j++)
                    if(i!=j)
                        sum+=Dis(p[i],p[j]);
                 ans=min(sum,ans);
            }
        }
        printf("%.4lf\n",ans);
    }
    return 0;
}
时间: 2024-12-25 06:51:38

HDU3694 Fermat Point in Quadrangle(求四边形费马点)的相关文章

hdu3694 Fermat Point in Quadrangle 求四边形费马点

http://acm.hdu.edu.cn/showproblem.php?pid=3694 Fermat Point in Quadrangle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1973    Accepted Submission(s): 361 Problem Description In geometry the

poj 3990 Fermat Point in Quadrangle 凸包和费马点

题意: 求一个四边形的费马点. 分析: 模拟退火要么超时要么wa,这题的数据就是不想让随机算法过的..其实四边形的费马点很简单,如果是凸四边形的话费马点是对角线交点,如果是凹四边形费马点是凹点.但题目给的四个点顺序是不确定的,所以要先求下凸包. 代码: //poj 3990 //sep9 #include <iostream> #include <cmath> #include <algorithm> using namespace std; struct Point

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 3694 Fermat Point in Quadrangle (费马定理求四边形的费马点)

题意:给你四个点,找出一个点到四个点的距离最小 四边形的费马点:凸边形是两对角线的交点,凹边形式凹点. PS: 三角形的费马点: 1.若三角形3个内角均小于120°,那么3条距离连线正好三等分费马点所在的周角,即该点所对三角形三边的张角相等,均为120°.所以三角形的费马点也称为三角形的等角中心. 2.若三角形有一内角大于等于120°,则此钝角的顶点就是距离和最小的点. #include<stdio.h> #include<string.h> #include<stdlib.

hdu4386(求四边形最大面积)

题意:给出一个四边形的边长,求四边形最大面积.不合法输出-1: 解法:比较明显的三分,先枚举四边形的边的连接,然后三分一个对角线长度.但是比较怪异的是eps取1e-8wa了,去1e-7才可以过.不知道谁可以解释一下. 还有这题还有一个结论,后来才知道的.len是周长的二分之一.area=sqrt((len-a)*(len-b)*(len-c)*(len-d)); 三分代码: /****************************************************** * aut

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

求逆元的四种算法(拓欧费马小线性推欧拉)

求逆元的四种算法 拓展欧几里得算法求逆元 上一篇博客中已经讲过拓展欧几里得算法,并且讲解了求逆元的原理.这里只列出代码 在要求逆元的数与p互质时使用 代码 //扩展欧几里得定理 int ex_gcd(int a,int b,int& x,int& y) { if(b==0) { x=1; y=0; return a; } int ans = ex_gcd(b,a%b,x,y); int tmp = x; x = y; y = tmp-a/b*y; return ans; } int cal

费马小定律求逆元

#include<iostream> #include<cstdio> using namespace std; typedef long long ll; ll n,p,inv[3001000]; ll rd(){ ll x=0,fl=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')fl=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x&

费马小定理 求乘法逆元

//P3811 [模板]乘法逆元 #include<bits/stdc++.h> using namespace std; inline void write(long long X) { if(X<0) {X=~(X-1); putchar('-');} if(X>9) write(X/10); putchar(X%10+'0'); } long long qpow(long long n,long long m,long long mod) { long long ans=1;