poj 1039

#include  <iostream>
#include  <algorithm>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include   <cassert>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
using namespace std;
const int maxn=30;
const double eps=1e-3;
int sgn(double x){ if(fabs(x) < eps) return 0;  if(x >0) return 1; return -1; }
int dcmp(double x, double y){ if(fabs(x - y) < eps) return 0; if(x > y) return 1;return -1;}
struct Point  { double x,y; Point(double x,double y)      { x=x;y=y; };  Point() {};  };
struct Segment{ Point a,b;  Segment(Point x,Point y )     { a=x;b=y; };  Segment(){}; };
struct Line   { Point a,b;  Line(Point x,Point y )        { a=x;b=y; };  Line(){};    };
typedef Point Vector;
/*Vector operator + (Vector A, Vector B){ return Vector(A.x+B.x, A.y+B.y); } // 向量相加
Vector operator - (Point  A, Point  B){ return Vector(B.x-A.x, B.y-A.y); } // 向量生成   A-B;
double operator * (Vector A, Vector B){ return A.x*B.x-A.y*B.y;          } // 点积
double operator ^ (Vector A, Vector B){ return A.x*B.y-A.y*B.x;          } // 叉积*/
double Dot(Vector A, Vector B)   { return A.x*B.x + A.y*B.y; }  // 点积
double Cross(Vector A, Vector B) { return A.x*B.y-A.y*B.x;   }  // 叉积
double Length(Vector A)          { return sqrt(Dot(A, A));   } // 向量长度
double dis(Point a,Point b) { return sqrt( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) ); }
Point   pa[maxn];
Point   pb[maxn];
Line    sg[maxn];
int n;
double make(Line A,Line B)
{
    Point a=A.a; Point b=A.b;Point c=B.a; Point d=B.b;
    double A1=b.y-a.y,B1=-(b.x-a.x),C1=b.y*a.x-b.x*a.y;
    double A2=d.y-c.y,B2=-(d.x-c.x),C2=d.y*c.x-d.x*c.y;
    double k=A1*B2-A2*B1;
    double x=-(B1*C2-C1*B2)*1.000000000/k;
    double y=(A1*C2-C1*A2)*1.00000000/k;
    return x;
}
bool co(Line A,Line B)
{
    Point  a=A.a; Point  b=A.b; Point  c=B.a;  Point  d=B.b;
    Vector x,y,xxx,yyy;
    x.x=c.x-a.x;    x.y=c.y-a.y;
    y.x=d.x-a.x;    y.y=d.y-a.y;
    xxx.x=c.x-b.x;  xxx.y=c.y-b.y;
    yyy.x=d.x-b.x;  yyy.y=d.y-b.y;
    if( Cross(x,y)*Cross(xxx,yyy)>eps ) return 0;
    else return 1;
}
double work(Point xx,Point yy)
{
    Line  qq; qq.a=xx;  qq.b=yy;

    //cout<<xx.x<<"  "<<xx.y<<endl;
    //cout<<yy.x<<"  "<<yy.x<<endl;

    double ans=-1e18;
    for(int i=1;i<=n;i++)
    {

        if(i==1)
        {
            if(co(sg[i],qq)==0) return ans;
        }
        else
        {
             if(co(sg[i],qq)==1)  ans=max(ans,make(sg[i],qq));
             else
             {
                 if(co(Line(pa[i],pa[i-1]),qq)==1) ans=max(ans,make(Line(pa[i],pa[i-1]),qq));
                 if(co(Line(pb[i],pb[i-1]),qq)==1) ans=max(ans,make(Line(pb[i],pb[i-1]),qq));
                 break;
             }
        }
    }
    return ans;
}
bool up(Point a,Point b)
{
    return a.x<b.x;
}
int main()
{
    while(1)
    {
        scanf("%d",&n);  if(n==0) { break; }
        for(int i=1;i<=n;i++) { scanf("%lf %lf",&pa[i].x,&pa[i].y);    }  // xia mian  dian
        sort(pa+1,pa+1+n,up);
        for(int i=1;i<=n;i++) { pb[i].x=pa[i].x; pb[i].y=pa[i].y+1.0;  }  // shang mian dian
        for(int i=1;i<=n;i++) { pa[i].y--;       pb[i].y--;            }  // 下移
        for(int i=1;i<=n;i++) { sg[i].a=pa[i];   sg[i].b=pb[i];        }  //  a xiao b shang
        double ans=-1e18;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++) // end
            {
                ans=max(ans,work(pa[i],pa[j]));
                ans=max(ans,work(pa[i],pb[j]));
                ans=max(ans,work(pb[i],pa[j]));
                ans=max(ans,work(pb[i],pb[j]));
            }
            //cout<<ans<<endl;
        }
        if(fabs(ans-pa[n].x)>eps ) printf("%.2f
",ans);
        else printf("Through all the pipe.
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Andromeda-Galaxy/p/10665982.html