码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2826 An Easy Problem?!(线段相交,分类讨论)

时间:2015-07-25 20:05:44      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:线段相交   分情况讨论   

题意:给两个线段,问他们能收集到多少雨水。
链接:http://poj.org/problem?id=2826

解法:分四种情况讨论
1. 存在一个线段与x轴平行,答案为0
2. 两个线段没有交点,答案为0
3. 1和2都不满足时,令线段1为比较低的那个线段,且p1为其比较高的那个点,若该点往y轴正方向的射线与线段2有交点,则答案为0
4. 3不满足时,求出两线段交点x1,p1做一条平行于x轴的线,该线与线段2的交点x2,则三角形x1, x2, p1的面积就是答案

小结:此题属于分类讨论型的题,坑点很多。许多情况可以合并,注意不要分过多情况讨论,以免导致混乱。同时,poj的g++自带很多坑点,就不说了。

//Hello. I‘m Peter.
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
#define peter cout<<"i am peter"<<endl
typedef long long ll;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
const double eps = 1e-9, pi = acos(-1.0);
inline int sgn(double x){
    if(fabs(x) < eps) return 0;
    else return x > 0? 1 : -1;
}
struct Point{
    double x, y;
    Point(){};
    Point(double x1, double y1){x = x1, y = y1;}
};
typedef Point Vector;
bool cmpxy(const Point a, const Point b){if(sgn(a.x-b.x)) return a.x < b.x; else return a.y < b.y;}
bool cmpyx(const Point a, const Point b){if(sgn(a.y-b.y)) return a.y < b.y; else return a.x < b.x;}
bool cmpYx(const Point a, const Point b){if(sgn(a.y-b.y)) return a.y > b.y; else return a.x < b.x;}
bool cmpyX(const Point a, const Point b){if(sgn(a.y-b.y)) return a.y < b.y; else return a.x > b.x;}
Vector operator + (const Vector a, const Vector b){return Vector(a.x + b.x, a.y + b.y);}
Vector operator - (const Vector a, const Vector b){return Vector(a.x - b.x, a.y - b.y);}
double operator * (const Vector a, const Vector b){return a.x * b.x + a.y * b.y;}
double operator % (const Vector a, const Vector b){return a.x * b.y - a.y * b.x;}
Vector operator * (const Vector a, const double b){return Vector(a.x * b, a.y * b);}
Vector operator * (const double b, const Vector a){return Vector(a.x * b, a.y * b);}
Vector operator / (const Vector a, const double b){return Vector(a.x / b, a.y / b);}
bool operator == (const Point a, const Point b){return sgn(a.x - b.x)==0 && sgn(a.y - b.y)==0;}
bool operator || (const Vector a, const Vector b){return sgn(a % b)==0;}
bool operator / (const Vector a, const Vector b){return sgn(a % b)!=0;}
double Length(Vector v){return (double)sqrt((double)(v.x * v.x + v.y * v.y));}
double Dis(Point a, Point b){return Length(a - b);}
Vector Rotate(Vector v, double rad){return Vector(v.x * cos(rad) - v.y * sin(rad), v.x * sin(rad) + v.y * cos(rad));}
Vector Norv(Vector v){return Vector(v.y, -v.x);}
Vector Unitv(Vector v){return v / Length(v);}
double angle(Vector v){return atan2(v.y, v.x);}
//double angle(Vector a, Vector b){
//    double ans = angle(a) - angle(b);
//    while(sgn(ans) < 0) ans += 2*pi; while(sgn(ans) >= 2*pi) ans -= 2*pi;
//    return fmin(ans, 2*pi - ans);
//}
double Area_Tri(Point p1, Point p2, Point p3){return 0.5 * fabs((p2 - p1) % (p3 - p1));}
double Area_Tri(double a, double b, double c){
    double p = (a+b+c)/2;
    return (double)sqrt((double)(p*(p-a)*(p-b)*(p-c)));
}
double Area_Polygon(Point *p, int n){
    //求任意简单多边形的无向面积,前提要将p逆时针或顺时针排序

    if(n <= 2) return 0;
    Point o = Point(0, 0);
    p[n++] = p[0];
    double ans = 0;
    for(int i = 0; i < n-1; i++){
        ans += Area_Tri(o, p[i], p[i+1]) * (sgn((p[i] - o) % (p[i+1] - o)) < 0? -1 : 1);
    }
    return fabs(ans);
}


/*--------------------------直线--------------------------*/
struct Line{
    Point p; Vector v;
    Line(){};
    Line(Point p1, Vector v1){p = p1, v = v1;}
};
Point operator / (const Line a, const Line b){
    double t = ((b.p - a.p) % b.v) / (a.v % b.v);
    return a.p + a.v * t;
}
double Dis(Point p, Line l){return fabs(l.v % (p - l.p)) / Length(l.v);}
//double angle(Line a, Line b){double ans = angle(a.v, b.v); return fmin(ans, pi - ans);}
//double angle(Line l){
//    double a = angle(Vector(1, 0), l.v);
//    if(Rotate(Vector(1, 0), a) / l.v) a = pi - a;
//    return a;
//}


/*--------------------------线段--------------------------*/
struct Seg{
    Point p1, p2;
    Seg(){};
    Seg(Point p11, Point p22){p1 = p11, p2 = p22;}
};
bool PointOnSeg(Point p, Seg s){
    if((s.p1 - p) / (s.p2 - p)) return false;
    else if(sgn((s.p1 - p) * (s.p2 - p)) > 0) return false;
    else return true;
}
bool operator / (const Seg a, const Seg b){//need change
    if((a.p2 - a.p1) || (b.p2 - b.p1)){
        return PointOnSeg(a.p1, b) || PointOnSeg(a.p2, b) ||
        PointOnSeg(b.p1, a) || PointOnSeg(b.p2, a);
    }
    else return sgn((a.p2 - a.p1) % (b.p1 - a.p1)) * sgn((a.p2 - a.p1) % (b.p2 - a.p1)) <= 0 &&
    sgn((b.p2 - b.p1) % (a.p1 - b.p1)) * sgn((b.p2 - b.p1) % (a.p2 - b.p1)) <= 0 ;
}
bool operator / (const Line a, const Seg b){
    return sgn(a.v % (b.p1 - a.p)) * sgn(a.v % (b.p2 - a.p)) <= 0;
}

Point readPoi(){
    int x = read(), y = read();
    return Point(x, y);
}

int main(){
    int T = read();
    for(int kase = 1; kase <= T; kase++){
        Seg s1, s2;
        s1.p1 = readPoi(), s1.p2 = readPoi();
        s2.p1 = readPoi(), s2.p2 = readPoi();

        double ans = 0.0;
        if(((s1.p2 - s1.p1) || Vector(1,0)) || ((s2.p2 - s2.p1) || Vector(1,0))){
            ans = 0.0;
        }
        else if(!(s1 / s2)){
            ans = 0.0;
        }
        else{
            if(s1.p1.y < s1.p2.y) swap(s1.p1, s1.p2);
            if(s2.p1.y < s2.p2.y) swap(s2.p1, s2.p2);
            if(s1.p1.y < s2.p1.y) swap(s1, s2);

            if(Seg(s2.p1, s2.p1 + Vector(0, 1e6)) / s1){
                ans = 0.0;
            }
            else{
                Point x = Line(s1.p1, s1.p2 - s1.p1) / Line(s2.p1, s2.p2 - s2.p1);
                Point x2 = Line(s2.p1, Vector(1,0)) / Line(s1.p1, s1.p2 - s1.p1);
                ans = Area_Tri(x, x2, s2.p1);
            }
        }

        printf("%.2f\n",ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 2826 An Easy Problem?!(线段相交,分类讨论)

标签:线段相交   分情况讨论   

原文地址:http://blog.csdn.net/uestc_peterpan/article/details/47058661

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!