zoukankan      html  css  js  c++  java
  • Pipe

    题目大意:有一个不反光并且不透光的管道,现在有一束光线从最左端进入,问能达到的最右端是多少,输出x坐标。
     
    分析:刚开始做是直接枚举两个点然后和管道进行相交查询,不过这样做需要考虑的太多,细节不容易掌控。后来发现其实只需要对接口进行一下相交查询就简单多了,因为只需要考虑能不能通过每个截口就可以了,而且这样做的好处还有没有平行线和重叠线的情况,因为所有的截口都是垂直于x轴的,换一种想法海阔太空啊。
     
    代码如下:
    ==========================================================================================================================
    #include<stdio.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 107;
    const double EPS = 1e-8;
    const double oo = 1e9+7;
    
    int Sign(double t)
    {
        if(t > EPS)return 1;
        if(fabs(t)<EPS)return 0;
        return -1;
    }
    
    struct Point
    {
        double x, y;
        Point(double x=0, double y=0):x(x), y(y){}
        Point operator - (const Point &t)const{
            return Point(x-t.x, y-t.y);
        }
        double operator ^(const Point &t)const{
            return x*t.y - y*t.x;
        }
        bool operator == (const Point &t)const{
            return fabs(x-t.x)<EPS && fabs(y-t.y)<EPS;
        }
    };
    struct Segment
    {
        Point S, E;
        double a, b, c;///ax + by = c;
    
        Segment(Point S=0, Point E=0):S(S),E(E){
            ///求线段所在的直线的常数项
            a = S.y - E.y;
            b = E.x - S.x;
            c = E.x*S.y - S.x*E.y;
        }
        bool Inters(const Segment &tmp) const{
            int t1 = Sign((S-E)^(tmp.S-E));
            int t2 = Sign((S-E)^(tmp.E-E));
            ///不存在平行,或者共线情况,有一点相交都算相交
            if(t1+t2==2 || t1+t2==-2)
                return false;
            else
                return true;
        }
        Point crossNode(const Segment &tmp)const{
            ///求交点
            Point t;
            t.x = (c*tmp.b-tmp.c*b) / (a*tmp.b-tmp.a*b);
            t.y = (c*tmp.a-tmp.c*a) / (b*tmp.a-tmp.b*a);
    
            return t;
        }
        void MakeNewSeg(double Lx, double Rx)
        {///构造新的线段,与原来的线段共线
            S.x = Lx, S.y = (c-a*Lx) / b;
            E.x = Rx, E.y = (c-a*Rx) / b;
        }
    };
    
    double FindMinX(Segment s, Segment sg[], int N)
    {
        double ans=oo;
    
        for(int i=1; i<N; i++)
        {
            if(s.Inters(sg[i]))
                continue;
    
            Segment t1(sg[i-1].S, sg[i].S);
            Segment t2(sg[i-1].E, sg[i].E);
    
            if(s.Inters(t1))
            {
                Point tmp = s.crossNode(t1);
                ans = tmp.x;
            }
            if(s.Inters(t2))
            {
                Point tmp = s.crossNode(t2);
    
                if(fabs(ans-oo) < EPS)
                    ans = tmp.x;
                else
                    ans = max(ans, tmp.x);
            }
    
            break;
        }
    
        return ans;
    }
    
    int main()
    {
        int N;
    
        while(scanf("%d", &N) != EOF && N)
        {
            Point p[MAXN];
            Segment sg[MAXN];
    
            int k=0;
    
            for(int i=0; i<N; i++, k+=2)
            {
                scanf("%lf%lf", &p[k].x, &p[k].y);
                p[k+1].x = p[k].x, p[k+1].y = p[k].y - 1.0;
                sg[i] = Segment(p[k], p[k+1]);
            }
    
            double ans = -oo;
    
            for(int i=0; i<k; i++)
            for(int j=i+1; j<k; j++)
            {
                if(fabs(p[i].x-p[j].x) < EPS)
                    continue;
    
                Segment s(p[i], p[j]);
                s.MakeNewSeg(sg[0].S.x, sg[N-1].S.x);
    
                if(s.Inters(sg[0]))
                    ans = max(ans, FindMinX(s, sg, N));
               /// printf("i=%d, j=%d, ans=%f
    ", i, j, ans);
            }
    
            if(fabs(ans-oo) < EPS)
                printf("Through all the pipe.
    ");
            else
                printf("%.2f
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    W3C help
    css值解析
    css中的格式上下文Formatting Context
    css中绝对定位中的left和top属性
    事件模型
    程序员应该如何更有效率
    css的边偏移距离
    css插入框
    css中的whitespace属性
    源码安装nginx 方法二
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4796301.html
Copyright © 2011-2022 走看看