zoukankan      html  css  js  c++  java
  • POJ 1410 Intersection 数据错误

    题目要求判断一条线段和一个矩形是否相交,或者是否在矩形里面(题目好像没说?)

    思路就是直接暴力判断和矩形四条边是否相交,和线段的坐标是否在矩形的坐标范围即可。

    然后题目的数据,(xleft,ytop) 和 (xright,ybottom)不是按顺序给出的,需要自己判断下顺序。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 5000+20;
    struct coor
    {
        double x,y;
        coor(){}
        coor(double xx,double yy):x(xx),y(yy){}
        double operator ^(coor rhs) const //计算叉积(向量积)
        {
            return x*rhs.y - y*rhs.x;
        }
        coor operator -(coor rhs) const //坐标相减,a-b得到向量ba
        {
            return coor(x-rhs.x,y-rhs.y);
        }
        double operator *(coor rhs) const //数量积
        {
            return x*rhs.x + y*rhs.y;
        }
    }a,b;
    struct Line
    {
        coor point1,point2;
        Line(){}
        Line(coor xx,coor yy):point1(xx),point2(yy){}
    }line[maxn],seg;
    const double eps = 1e-14;
    bool same (double a,double b)
    {
        return fabs(a-b)<eps;
    }
    bool OnSegment (coor a,coor b,coor c) //判断点C是否在线段ab上
    {
        double min_x = min(a.x,b.x), min_y = min(a.y,b.y);
        double max_x = max(a.x,b.x), max_y = max(a.y,b.y);
        if (c.x>=min_x && c.x<=max_x && c.y>=min_y && c.y<=max_y) return true;
        else return false;
    }
    bool SegmentIntersect (coor a,coor b,coor c,coor d)
    {
        double d1 = (b-a)^(d-a); //direction(a,b,d);以a为起点,计算ab和ab的叉积
        double d2 = (b-a)^(c-a);
        double d3 = (d-c)^(a-c);
        double d4 = (d-c)^(b-c);
        if (d1*d2<0 && d3*d4<0) return true;
        else if (same(d1,0) && OnSegment(a,b,d)) return true;
        else if (same(d2,0) && OnSegment(a,b,c)) return true;
        else if (same(d3,0) && OnSegment(c,d,a)) return true;
        else if (same(d4,0) && OnSegment(c,d,b)) return true;
        else return false;
    }
    void work ()
    {
        scanf("%lf%lf%lf%lf",&seg.point1.x,&seg.point1.y,&seg.point2.x,&seg.point2.y);
        scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
        if (a.x > b.x) swap(a.x,b.x);
        if (a.y < b.y) swap(a.y,b.y);
        line[1] = Line(a,coor(b.x,a.y));
        line[2] = Line(coor(a.x,b.y),b);
        line[3] = Line(a,coor(a.x,b.y));
        line[4] = Line(coor(b.x,a.y),b);
        for (int i=1;i<=4;++i)
        {
            if (SegmentIntersect(seg.point1,seg.point2,line[i].point1,line[i].point2))
            {
                printf ("T
    ");
                return ;
            }
        }
        if (seg.point1.x>=a.x&&seg.point1.x<=b.x&&seg.point2.x>=a.x&&seg.point2.x<=b.x
          &&seg.point1.y>=b.y&&seg.point1.y<=a.y&&seg.point2.y>=b.y&&seg.point2.y<=a.y)
          {
              printf ("T
    ");
              return ;
          }
        printf ("F
    ");
        return ;
    }
    
    int main()
    {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        int t;
        cin>>t;
        while(t--) work();
        return 0;
    }
    View Code

    然而这题应该用判断点在多边形里比较好

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 5000+20;
    struct coor
    {
        double x,y;
        coor(){}
        coor(double xx,double yy):x(xx),y(yy){}
        double operator ^(coor rhs) const //计算叉积(向量积)
        {
            return x*rhs.y - y*rhs.x;
        }
        coor operator -(coor rhs) const //坐标相减,a-b得到向量ba
        {
            return coor(x-rhs.x,y-rhs.y);
        }
        double operator *(coor rhs) const //数量积
        {
            return x*rhs.x + y*rhs.y;
        }
    }a,b,liu[maxn];
    struct Line
    {
        coor point1,point2;
        Line(){}
        Line(coor xx,coor yy):point1(xx),point2(yy){}
    }line[maxn],seg;
    const double eps = 1e-14;
    bool same (double a,double b)
    {
        return fabs(a-b)<eps;
    }
    bool OnSegment (coor a,coor b,coor c) //判断点C是否在线段ab上
    {
        double min_x = min(a.x,b.x), min_y = min(a.y,b.y);
        double max_x = max(a.x,b.x), max_y = max(a.y,b.y);
        if (c.x>=min_x && c.x<=max_x && c.y>=min_y && c.y<=max_y) return true;
        else return false;
    }
    bool SegmentIntersect (coor a,coor b,coor c,coor d)
    {
        double d1 = (b-a)^(d-a); //direction(a,b,d);以a为起点,计算ab和ab的叉积
        double d2 = (b-a)^(c-a);
        double d3 = (d-c)^(a-c);
        double d4 = (d-c)^(b-c);
        if (d1*d2<0 && d3*d4<0) return true;
        else if (same(d1,0) && OnSegment(a,b,d)) return true;
        else if (same(d2,0) && OnSegment(a,b,c)) return true;
        else if (same(d3,0) && OnSegment(c,d,a)) return true;
        else if (same(d4,0) && OnSegment(c,d,b)) return true;
        else return false;
    }
    bool PointInPolygon (coor p[],int n,coor cmp)
    {
        //思路:求解y=cmp.y与多边形一侧有多少个交点,奇数就在里面,偶数就在外面,cmp在边上是不行的
        int cnt = 0; //记录单侧有多少个交点,这里的p[],必须有顺序
        for (int i=1;i<=n;++i)
        {
            int t = (i+1)>n ? 1:(i+1);  //下标为1要这样
            coor p1=p[i],p2=p[t];
            if (cmp.y >= max(p1.y,p2.y)) continue;//交点在延长线上和在凸顶点都不要
            if (cmp.y <  min(p1.y,p2.y)) continue;//交点在凹顶点上就要,这里没取等
            if (same(p1.y,p2.y)) continue; //与cmp.y是平行的
            double x = (cmp.y-p1.y)*(p1.x-p2.x)/(p1.y-p2.y) + p1.x; //求交点 p1.y != p2.y不会除0错误
            if (x>cmp.x) cnt++;//只统计一侧的交点
        }
        return cnt&1;
    }
    void work ()
    {
        scanf("%lf%lf%lf%lf",&seg.point1.x,&seg.point1.y,&seg.point2.x,&seg.point2.y);
        scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
        if (a.x > b.x) swap(a.x,b.x);
        if (a.y < b.y) swap(a.y,b.y);
        line[1] = Line(a,coor(b.x,a.y));
        line[2] = Line(coor(a.x,b.y),b);
        line[3] = Line(a,coor(a.x,b.y));
        line[4] = Line(coor(b.x,a.y),b);
    
        liu[1]=a;
        liu[2]=coor(b.x,a.y);
        liu[3]=b;
        liu[4]=coor(a.x,b.y);
    
        for (int i=1;i<=4;++i)
        {
            if (SegmentIntersect(seg.point1,seg.point2,line[i].point1,line[i].point2))
            {
                printf ("T
    ");
                return ;
            }
        }
        if (PointInPolygon(liu,4,seg.point1)&&PointInPolygon(liu,4,seg.point2))
        {
            printf ("T
    ");
            return ;
        }
        printf ("F
    ");
        return ;
    }
    
    int main()
    {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        int t;
        cin>>t;
        while(t--) work();
        return 0;
    }
    View Code
  • 相关阅读:
    HEOI2016 题解
    数据结构考前复习【已弃】
    BZOJ 3993: [SDOI2015]星际战争 [二分答案 二分图]
    BZOJ 4698: Sdoi2008 Sandy的卡片 [后缀自动机]
    BZOJ 3990: [SDOI2015]排序 [搜索]
    字符串考前总结
    BZOJ 3881: [Coci2015]Divljak [AC自动机 树链的并]
    CF698C. LRU [容斥原理 概率]
    BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]
    BZOJ 1444: [Jsoi2009]有趣的游戏 [AC自动机 高斯消元]
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5774249.html
Copyright © 2011-2022 走看看