• 简单几何(线段相交) POJ 2826 An Easy Problem?!


    题目传送门

    题意:两条线段看成两块木板,雨水从上方往下垂直落下,问能接受到的水的体积

    分析:恶心的分类讨论题,考虑各种情况,尤其是入口被堵住的情况,我的方法是先判断最高的两个点是否在交点的同一侧,然后看看是否高的点覆盖了低的点,用叉积判断方向,其他的情况见网上的解释。貌似没有什么卡精度的数据。最后膜拜楼教主,难以望其项背。。。

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015/10/30 星期五 18:36:27
    * File Name     :POJ_2826.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    const double EPS = 1e-10;
    const double PI = acos (-1.0);
    int dcmp(double x)  {
        if (fabs (x) < EPS) return 0;
        else    return x < 0 ? -1 : 1;
    }
    struct  Point   {
        double x, y;
        Point () {}
        Point (double x, double y) : x (x), y (y) {}
        Point operator + (const Point &r) const {
            return Point (x + r.x, y + r.y);
        }
        Point operator - (const Point &r) const {
            return Point (x - r.x, y - r.y);
        }
        Point operator * (double p) const {
            return Point (x * p, y * p);
        }
        Point operator / (double p) const {
            return Point (x / p, y / p);
        }
        bool operator < (const Point &r) const {
            return x < r.x || (!dcmp (x - r.x) && y < r.y);
        }
        bool operator == (const Point &r) const {
            return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
        }
    };
    typedef Point Vector;
    Point read_point(void)  {
        double x, y;
        scanf ("%lf%lf", &x, &y);
        return Point (x, y);
    }
    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;
    }
    Point line_line_inter(Point p, Vector V, Point q, Vector W) {
        Vector U = p - q;
        double t = cross (W, U) / cross (V, W);
        return p + V * t;
    }
    bool can_inter(Point a1, Point a2, Point b1, Point b2)  {
        double c1 = cross (a2 - a1, b1 - a1), c2 = cross (a2 - a1, b2 - a1),
               c3 = cross (b2 - b1, a1 - b1), c4 = cross (b2 - b1, a2 - b1);
        return dcmp (c1) * dcmp (c2) <= 0 && dcmp (c3 * c4) <= 0;
    }
    double area_triangle(Point a, Point b, Point c) {
        return fabs (cross (b - a, c - a)) / 2.0;
    }
    
    int main(void)    {
        int T;  scanf ("%d", &T);
        Point a1, a2, b1, b2;
        while (T--) {
            a1 = read_point ();
            a2 = read_point ();
            b1 = read_point ();
            b2 = read_point ();     //a1,b1是纵坐标较高的点
            if (dcmp (a1.y - a2.y) < 0 || (dcmp (a1.y - a2.y) == 0 && dcmp (a1.x - a2.x) > 0))    swap (a1, a2);
            if (dcmp (b1.y - b2.y) < 0 || (dcmp (b1.y - b2.y) == 0 && dcmp (b1.x - b2.x) > 0))    swap (b1, b2);
            if (dcmp (a1.x - a2.x) == 0 && dcmp (b1.x - b2.x) == 0)  {      //竖直平行
                puts ("0.00");  continue;
            }
            if (dcmp (a1.y - a2.y) == 0 || dcmp (b1.y - b2.y) == 0)  {      //水平平行
                puts ("0.00");  continue;
            }
            if (dcmp (cross (a1 - a2, b1 - b2)) == 0)   {                   //共线
                puts ("0.00");  continue;
            }
            if (!can_inter (a1, a2, b1, b2))    {                           //不能相交
                puts ("0.00");  continue;
            }
            Point p = line_line_inter (a1, a2 - a1, b1, b2 - b1), q;
            if (dcmp (a1.y - p.y) <= 0 || dcmp (b1.y - p.y) <= 0)   {       //有一个点纵坐标低于交点
                puts ("0.00");  continue;
            }
            double ans = 0.0;
            if (dcmp (a1.y - b1.y) == 0)    {
                ans = area_triangle (a1, b1, p);
            }
            else if (dcmp (a1.y - b1.y) < 0)   {
                if (dcmp (a1.x - p.x) > 0 && dcmp (b1.x - p.x) > 0)   {
                    if (dcmp (b1.x - a1.x) >= 0 && cross (a1 - p, b1 - p) >= 0)    {    //入口被覆盖,以下同
                        puts ("0.00");  continue;
                    }
                }
                else if (dcmp (a1.x - p.x) < 0 && dcmp (b1.x - p.x) < 0)  {
                    if (dcmp (b1.x - a1.x) <= 0 && cross (b1 - p, a1 - p) >= 0)    {
                        puts ("0.00");  continue;
                    }
                }
                q = line_line_inter (a1, Vector (1, 0), b1, b2 - b1);
                ans = area_triangle (a1, q, p);
            }
            else    {
                if (dcmp (a1.x - p.x) > 0 && dcmp (b1.x - p.x) > 0)   {
                    if (dcmp (a1.x - b1.x) >= 0 && cross (b1 - p, a1 - p) >= 0)    {
                        puts ("0.00");  continue;
                    }
                }
                else if (dcmp (a1.x - p.x) < 0 && dcmp (b1.x - p.x) < 0)  {
                    if (dcmp (a1.x - b1.x) <= 0 && cross (a1 - p, b1 - p) >= 0)    {
                        puts ("0.00");  continue;
                    }
                }
                q = line_line_inter (a1, a2 - a1, b1, Vector (1, 0));
                ans = area_triangle (b1, q, p);
            }
            double eps = 1e-8;
            printf ("%.2f
    ", ans + eps);
        }
    
       //cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.
    ";
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    decimal赋值
    "errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest hint: [d0tQ_02368635
    scope.row中属性值展示
    echarts.baidu 官网
    PowerDesigner使用
    解决 office2016 意外的严重错误 不能启动程序
    Jenkins 关闭和重启
    解决 weblogic poi3.9 报错 a different type with name "javax/xml/namespace/QName"
    WINDOWS7 下 xclient 802.1x 客户端 停止运行的解决办法
    前台进程转后台运行
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4925016.html
Copyright © 2020-2023  润新知