zoukankan      html  css  js  c++  java
  • 【POJ 2826】An Easy Problem?!(几何、线段)

    两个木条装雨水能装多少。

    两线段相交,且不遮盖的情况下才可能装到水。

    求出交点,再取两线段的较高端点的较小值h,(h-交点的y)为三角形的高。

    三角形的宽即为(h带入两条线段所在直线得到的横坐标的差值)。

    三角形的面积即为雨水的量。

    坑点:如果用G++提交,ans要加上eps才能过,c++提交则没问题。

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #define MAX 1<<31
    #define dd double
    using namespace std;
    struct P {dd x,y;};
    struct L{
        P s,e;
        void input(){
            scanf("%lf%lf%lf%lf",&s.x,&s.y,&e.x,&e.y);
            if(s.x>e.x)swap(s,e);
        }
        dd k(){//斜率
            if(s.x==e.x)return MAX;
            return (s.y-e.y)/(s.x-e.x);
        }
        dd highX(){//较高端点的x值
            if(s.y>e.y)return s.x;
            return e.x;
        }
    }a,b;
    dd xmult(P a,P b,P o){//叉积
        return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
    }
    bool isCross(L a,L b){//是否相交
        return xmult(a.s,a.e,b.s)*xmult(a.s,a.e,b.e)<=0;//取等号就包括端点在另一线段的情况
    }
    P getCross(L a,L b){
        P c;
        dd ka=a.k(),kb=b.k();
        if(ka==MAX){//a是竖直的
            c.x=a.s.x;
            c.y=(c.x-b.s.x)*kb+b.s.y;
        }
        else{
            if(kb==MAX)
                c.x=b.s.x;
            else
                c.x=(a.s.y-b.s.y-ka*a.s.x+kb*b.s.x)/(kb-ka);
            c.y=(c.x-a.s.x)*ka+a.s.y;
        }
        return c;
    }
    dd getx(L a,dd y){//a所在直线上纵坐标为y的点的x
        if(a.s.y==a.e.y)return a.s.x;
        return (y-a.s.y)*(a.s.x-a.e.x)/(a.s.y-a.e.y)+a.s.x;
    }
    bool shadow(L a,L b){//是否遮盖
        dd x1=a.highX(),x2=b.highX();
            //如果倾斜方向一样,k大的线段的较高端点的x也更大则遮盖了
            //并且斜率相同的线段也会返回true
        return a.k()*b.k()>0&&(a.k()-b.k())*(x1-x2)>=0;
    }
    void solve(){
        double ans=0;
        if(a.k()&&b.k()&&isCross(a,b)&&isCross(b,a)&&!shadow(a,b)){
            P c=getCross(a,b);
            dd h=min(max(a.s.y,a.e.y),max(b.s.y,b.e.y));
            dd w=fabs(getx(a,h)-getx(b,h));
            ans=(h-c.y)*w/2.0;
        }
        printf("%.2f
    ",ans);
    }
    int main() {
        int t;
        cin>>t;
        while(t--){
            a.input();
            b.input();
            solve();
        }
    }
  • 相关阅读:
    博客园电子期刊2012年6月刊发布啦
    如何在博客园发博客时插入优酷视频
    上周热点回顾(7.167.22)
    “Coding changes the world” 博客园2012主题T恤专题上线
    [转]MySql查询缓存机制
    淘宝店铺开发 ShopSDK 1.x 及 TAE_SDK 2.0
    [转]NHibernate之旅系列文章导航
    MySQL 5.1参考手册 :: 7. 优化
    [转]Nant daily build实践
    [转]淘宝sdk——入门实战之footer.php制作
  • 原文地址:https://www.cnblogs.com/flipped/p/5722170.html
Copyright © 2011-2022 走看看