POJ 1039 Pipe

来源:互联网 发布:python twisted过时 编辑:程序博客网 时间:2024/04/30 17:35

题目大意就是给你一个管道,问你光线能够照到最右边的点的横坐标。

枚举任意两个端点构成直线,求其与最右边的竖线的交点,如果不相交,continue;

否则判断其与每条边的交点并判断是否在管道内部。

poj提交G++注意用%f,否则可能会WA。


CODE:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>using namespace std;#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)#define DOR(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)#define oo 1e6#define eps 1e-8#define nMax 100000#define pb push_back#define bug puts("OOOOh.....");#define zero(x) (((x)>0?(x):-(x))<eps)int dcmp(double x){    if(fabs(x)<eps) return 0;    return x>0?1:-1;}class point {public:    double x,y;    point (double x=0,double y=0):x(x),y(y) {}    void make(double _x,double _y) {x=_x;y=_y;}    void read() { scanf("%lf%lf",&x,&y); }    void out() { printf("%.2lf %.2lf\n",x,y);}    double len() { return sqrt(x*x+y*y); }    point friend operator - (point const& u,point const& v) {        return point(u.x-v.x,u.y-v.y);    }    point friend operator + (point const& u,point const& v) {        return point(u.x+v.x,u.y+v.y);    }    double friend operator * (point const& u,point const& v) {        return u.x*v.y-u.y*v.x;    }    double friend operator ^ (point const& u,point const& v) {        return u.x*v.x+u.y*v.y;    }    point friend operator * (point const& u,double const& k) {        return point(u.x*k,u.y*k);    }};typedef class line{public:    point a,b;    line() {}    line (point a,point b):a(a),b(b){}    void make(point u,point v) {a=u;b=v;}    void read() { a.read(),b.read(); }}segment;int dots_online(point u,point v,point w){    return dcmp((u-v)*(u-w)==0);}int parrel(line u,segment v) {    return dcmp((u.a-u.b)*(v.a-v.b))==0;}double solvey(line u,double x){    return (x-u.a.x)*(u.a.y-u.b.y)/(u.a.x-u.b.x)+u.a.y;}int oppitiside(line s,point u,point v,int o) {    if(parrel(s,line(u,v))) return 0;    if(o==1){        if(dcmp(solvey(s,u.x)-u.y)<=0 && dcmp(solvey(s,v.x)-v.y)<=0) return 0;    }else {        if(dcmp(solvey(s,u.x)-u.y)>=0 && dcmp(solvey(s,v.x)-v.y)>=0) return 0;    }    return dcmp((s.a-u)*(u-s.b))*dcmp((s.a-v)*(v-s.b))<=0;}point intersection(line l,segment s){    point ret = l.a;    double t=((l.a-s.a)*(s.a-s.b))/((l.a-l.b)*(s.a-s.b));    ret = ret + (l.b-l.a)*t;    return ret;}double x,ans,ans1;int n;point p[nMax];segment s[nMax];int o[nMax];#define dy 0.0001int main(){#ifndef ONLINE_JUDGE    freopen("input.txt","r",stdin);#endif    while(scanf("%d",&n),n){        for(int i=0;i<n;i++) {            p[i].read(),p[n+i].make(p[i].x,p[i].y-1.0);        }        for(int i=1;i<n;i++) {            s[i].make(p[i-1],p[i]);            s[i+n].make(p[n+i-1],p[i+n]);            o[i]=1;o[i+n]=0;        }        ans = p[0].x;        for(int k=0;k<2*n;k++){            for(int i=k+1;i<2*n;i++){                if(i==k+n) continue;                line l=line(p[k],p[i]);                point llf=intersection(l,segment(p[0],p[n]));                if(dcmp(llf.y-p[n].y)>=0 && dcmp(llf.y-p[0].y)<=0) ;else continue;                ans1 = p[n-1].x;                for(int j=1;j<2*n;j++){                    if(j==n)continue;                    if(oppitiside(l,s[j].a,s[j].b,o[j])){                        x = intersection(l,s[j]).x;                        ans1 = min(x,ans1);                    }                }                ans = max(ans,ans1);            }            if(dcmp(ans-p[n-1].x)>=0) break;        }        if(dcmp(ans-p[n-1].x)>=0) printf("Through all the pipe.\n");        else printf("%.2lf\n",ans);    }    return 0;}


原创粉丝点击