POJ 1556 计算几何基础

http://www.cnblogs.com/kuangbin/p/3189309.html

#include<iostream>
#include<iomanip>
#include<queue>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

const double eps=1e-8;

int sgn(double x)
{
    if (fabs(x)<eps) return 0;
    if (x<0) return -1;
    return 1;
}

struct Vector
{
    double x,y;
    Vector() {};
    Vector(double _x,double _y):x(_x),y(_y) {};
    Vector operator+(const Vector& b) const
    {
        return Vector(x+b.x,y+b.y);
    }
    Vector operator-(const Vector& b) const
    {
        return Vector(x-b.x,y-b.y);
    }
    Vector operator*(double q) const
    {
        return Vector(x*q,y*q);
    }
};

typedef Vector Point;

inline double DotProduct(const Vector& a,const Vector& b)
{
    return a.x*b.x+a.y*b.y;
}

inline double CrossProduct(const Vector& a,const Vector& b)
{
    return a.x*b.y-a.y*b.x;
}

struct Segment
{
    Point s,e;
    Segment() {};
    Segment(Point _s,Point _e):s(_s),e(_e) {};
};

bool IsIntersected(Segment l1,Segment l2)
{
    return max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
           max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
           max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
           max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
           sgn(CrossProduct(l2.s-l1.s,l1.e-l1.s))*sgn(CrossProduct(l2.e-l1.s,l1.e-l1.s)) <= 0 &&
           sgn(CrossProduct(l1.s-l2.s,l2.e-l2.s))*sgn(CrossProduct(l1.e-l2.s,l2.e-l2.s)) <= 0;
}

double Dist(Point a,Point b)
{
    return sqrt(DotProduct(b-a,b-a));
}

const int MAX=100;
const double INF=1e20;
Segment Seg[MAX];
double Dis[MAX][MAX];

int main()
{
    cin.sync_with_stdio(false);
    cout<<fixed<<setprecision(2);
    int n;
    double x,y1,y2,y3,y4;
    while (cin>>n&&n!=-1)
    {
        for (int i=1; i<=n; i++)
        {
            cin>>x>>y1>>y2>>y3>>y4;
            Seg[2*i-1]=Segment(Point(x,y1),Point(x,y2));
            Seg[2*i]=Segment(Point(x,y3),Point(x,y4));
        }
        for (int i=0; i<=4*n+1; i++)
            for (int j=0; j<=4*n+1; j++)
                if (i==j) Dis[i][j]=0;
                else Dis[i][j]=INF;
        for (int i=1; i<=4*n; i++)
        {
            int index=(i+3)/4;
            bool flag=true;
            Point temp;
            if (i&1) temp=Seg[(i+1)/2].s;
            else temp=Seg[(i+1)/2].e;
            for (int j=1; j<index; j++)
                if (IsIntersected(Seg[2*j-1],Segment(Point(0,5),temp))==false
                        &&IsIntersected(Seg[2*j],Segment(Point(0,5),temp))==false)
                    flag=false;
            if (flag)
                Dis[0][i]=Dis[i][0]=Dist(Point(0,5),temp);
            flag=true;
            for (int j=index+1; j<=n; j++)
                if (IsIntersected(Seg[2*j-1],Segment(temp,Point(10,5)))==false
                        &&IsIntersected(Seg[2*j],Segment(temp,Point(10,5)))==false)
                    flag=false;
            if (flag)
                Dis[i][4*n+1]=Dis[4*n+1][i]=Dist(temp,Point(10,5));
        }
        for (int i=1; i<=4*n; i++)
            for (int j=i+1; j<=4*n; j++)
            {
                int index1=(i+3)/4;
                int index2=(j+3)/4;
                bool flag=true;
                Point p1,p2;
                if (i&1) p1=Seg[(i+1)/2].s;
                else p1=Seg[(i+1)/2].e;
                if (j&1) p2=Seg[(j+1)/2].s;
                else p2=Seg[(j+1)/2].e;
                for (int k=index1+1;k<index2;k++)
                    if (IsIntersected(Seg[2*k-1],Segment(p1,p2))==false
                      &&IsIntersected(Seg[2*k],Segment(p1,p2))==false)
                      flag=false;
                if (flag) Dis[i][j]=Dis[j][i]=Dist(p1,p2);
            }
        bool flag=true;
        for (int i=1;i<=n;i++)
            if (IsIntersected(Seg[2*i-1],Segment(Point(0,5),Point(10,5)))==false
              &&IsIntersected(Seg[2*i],Segment(Point(0,5),Point(10,5)))==false)
              flag=false;
        if (flag) Dis[0][4*n+1]=Dis[4*n+1][0]=10;
        for (int k=0;k<=4*n+1;k++)
            for (int i=0;i<=4*n+1;i++)
                for (int j=0;j<=4*n+1;j++)
                    if (Dis[i][k]+Dis[k][j]<Dis[i][j])
                        Dis[i][j]=Dis[i][k]+Dis[k][j];
        cout<<Dis[0][4*n+1]<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值