• poj2826(线段相交)


    传送门:An Easy Problem?!

    题意:用两条线段接雨水,雨水是垂直落下的,问我们用给定的两条线段能接到多少水。

    分析:看起来很简单,写起来略麻烦,先排除不能接到水的情况:

         1. 两条线段不相交;

      2. 其中任意一条线段水平;

      3. 两条线段重合;

      4. 相交的情况下,最高的端点遮住了次高的端点

    最后求线段交点确定三角形并用叉积求面积。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <vector>
    #include <set>
    #include <string>
    #include <math.h>
    
    using namespace std;
    
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    const int N = 100010;
    int sgn(double x)
    {
        if(fabs(x) < eps)return 0;
        if(x < 0)return -1;
        else return 1;
    }
    struct Point
    {
        double x,y;
        Point(){}
        Point(double _x,double _y)
        {
            x = _x;y = _y;
        }
        Point operator -(const Point &b)const
        {
            return Point(x - b.x,y - b.y);
        }
        //叉积
        double operator ^(const Point &b)const
        {
            return x*b.y - y*b.x;
        }
    };
    struct Line
    {
        Point s,e;
        Line(){}
        Line(Point _s,Point _e)
        {
            s = _s;e = _e;
        }
        //两直线相交求交点
        //第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交
        //只有第一个值为2时,交点才有意义
        pair<int,Point> operator &(const Line &b)const
        {
            Point res=s;
            if(sgn((s-e)^(b.s-b.e))==0)
            {
                if(sgn((s-b.e)^(b.s-b.e))==0)
                    return make_pair(0,res);
                else return make_pair(1,res);
            }
            double t=((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
            res.x+=(e.x-s.x)*t;
            res.y+=(e.y-s.y)*t;
            return make_pair(2,res);
        }
    };
    //判断线段相交
    bool inter(Line l1,Line 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((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
        sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
    }
    int main()
    {
        int T;
        Line l1,l2;
        scanf("%d",&T);
        while(T--)
        {
            double a,b,c,d;
            scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
            l1=Line(Point(a,b),Point(c,d));
            scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
            l2=Line(Point(a,b),Point(c,d));
            if(sgn(l1.s.y-l1.e.y)==0||sgn(l2.s.y-l2.e.y)==0||!inter(l1,l2))
            {
                puts("0.00");
                continue;
            }
            if(sgn(l1.s.y-l1.e.y)<0)swap(l1.s,l1.e);
            if(sgn(l2.s.y-l2.e.y)<0)swap(l2.s,l2.e);
            if(inter(Line(l1.s,Point(l1.s.x,100000)),l2)||inter(Line(l2.s,Point(l2.s.x,100000)),l1))
            {
                puts("0.00");
                continue;
            }
            if(sgn(l1.s.y-l2.s.y)<0)
            {
                Point p=(l1&l2).second;
                Point p1=(Line(l1.s,Point(100000,l1.s.y))&l2).second;
                double ans=fabs((l1.s-p)^(p1-p))/2;
                printf("%.2lf
    ",ans);
            }
            else
            {
                Point p=(l1&l2).second;
                Point p1=(Line(l2.s,Point(100000,l2.s.y))&l1).second;
                double ans=fabs((l2.s-p)^(p1-p))/2;
                printf("%.2lf
    ",ans);
            }
        }
    }
    View Code
  • 相关阅读:
    date format记录
    python同时遍历两个list
    Windbg分析DMP文件
    DNS原理及其解析过程(转)
    有关正则表达式的详细内容
    sizeof _countof _tcslen的比较
    关于androidX
    UML类图
    springBoot 访问html页面遇到的坑
    hashmap 的实现原理
  • 原文地址:https://www.cnblogs.com/lienus/p/4333899.html
Copyright © 2020-2023  润新知