• WA on 23... Ural 1469


    http://acm.timus.ru/problem.aspx?space=1&num=1469

    #include <assert.h>
    #include <set>
    #include <algorithm>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int N = 5e4 + 100;
    const double EPS = 1e-5;
    int sgn(double x) {
        return x < -EPS ? -1 : EPS < x;
    }
    typedef double db;
    
    
    struct Poi {
        db x, y;
        Poi() {}
        Poi(db x, db y):x(x), y(y) {}
        bool operator < (const Poi&rhs) const {
            return sgn(x - rhs.x) < 0 || (sgn(x - rhs.x) == 0 && sgn(y - rhs.y) < 0);
        }
        bool operator == (const Poi&rhs) const{
            return sgn(x - rhs.x) == 0 && sgn(y - rhs.y) == 0;
        }
    };
    
    Poi operator - (Poi a, Poi b) {
        return Poi(a.x - b.x, a.y - b.y);
    }
    
    
    struct Seg {
        Poi a, b;
        void read() {
            scanf("%lf%lf%lf%lf", &a.x, &a.y, &b.x, &b.y);
            if (b < a) swap(a, b);
            assert(!(a == b));
        }
    } s[N];
    
    db cross(const Poi&a, const Poi&b) {
        return a.x * b.y  - a.y * b.x;
    }
    
    db dot(const Poi&a, const Poi&b) {
        return a.x * b.x + a.y * b.y;
    }
    
    bool onLeft(Seg s, Poi p) {
        return cross(p - s.a, s.b - s.a) > 0;
    }
    
    bool onSeg(Seg s, Poi p) {
        return sgn(cross(p - s.a, s.b - s.a)) == 0 && sgn(dot(p - s.a, s.b - s.a)) >= 0 && sgn(dot(p - s.b, s.a - s.b)) >= 0;
    }
    
    bool hasInter(int i, int j) {
        if (onSeg(s[i], s[j].a) || onSeg(s[i], s[j].b) || onSeg(s[j], s[i].a) || onSeg(s[j], s[i].b))
            return true;
        int a, b;
        a = onLeft(s[i], s[j].a);
        b = onLeft(s[i], s[j].b);
        if (a == b) return false;
        a = onLeft(s[j], s[i].a);
        b = onLeft(s[j], s[i].b);
        if (a == b) return false;
        return true;
    }
    
    struct Event {
        int type; // 0 for left end, 1 for right end
        int segId;
        Poi *p;
        Event() {}
        Event(int type, int segId, Poi*p):type(type), segId(segId), p(p) {}
        bool operator < (const Event&rhs) const {
            return *p < *rhs.p || (*p == *rhs.p && type < rhs.type);
        }
    };
    struct EventQueue:vector<Event> {
        int cur;
        Event* nextEvent() {
            if (cur < size())
                return &at(cur++);
            return NULL;
        }
    } EQ;
    
    void end(int i, int j) {
        puts("YES");
        printf("%d %d
    ", i, j);
        exit(0);
    }
    
    struct TNode;
    
    typedef set<TNode>::iterator iter;
    struct TNode {
        int segId;
        TNode(int segId):segId(segId) {}
        bool operator < (const TNode&rhs) const {
            if (rhs.segId != segId && hasInter(rhs.segId, segId))
                end(segId, rhs.segId);
            int t = sgn(cross(s[rhs.segId].a - s[segId].a, s[segId].b - s[segId].a));
            return t < 0;
        }
        bool operator == (const TNode&rhs) const {
            return segId == rhs.segId;
        }
    };
    
    iter pos[N];
    
    struct SweepLine:set<TNode> {
    
        bool add(Event*e, int&i, int&j) {
            pos[e->segId] = insert(TNode(e->segId)).first;
            iter it = pos[e->segId];
            iter pre = it, suf = it;
            --pre, ++suf;
            i = it->segId;
            if (pre != end()) {
                j = pre->segId;
                if (i != j && hasInter(i, j)) {
                    return true;
                }
            }
            if (suf != end()) {
                j = suf->segId;
                if (i != j && hasInter(i, j)) {
                    return true;
                }
            }
            return false;
        }
    
        bool del(Event*e, int &i, int&j) {
            iter it = pos[e->segId];
            iter pre = it, suf = it;
            --pre, ++suf;
            if (pre != end() && suf != end()) {
                i = pre->segId, j = suf->segId;
                if (i != j && hasInter(i, j))
                    return true;
            }
            erase(it);
            return false;
        }
    
    } SL;
    
    int main() {
    #ifdef lol
        freopen("1469.in", "r", stdin);
        freopen("1469.out", "w", stdout);
    #endif
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            s[i].read();
        }
        
        for (int i = 1; i <= n; ++i) {
            EQ.push_back(Event(0, i, &s[i].a));
            EQ.push_back(Event(1, i, &s[i].b));
        }
        sort(EQ.begin(), EQ.end());
    
    
        Event* e;
        int i, j;
        bool ok = false;
        while (!ok && (e = EQ.nextEvent()) != NULL) {
        //    printf("%d %d
    ", e->type, e->segId);
            if (e->type == 0) {
                if (SL.add(e, i, j))
                    ok = true;
            } else {
                if (SL.del(e, i, j))
                    ok = true;
            }
        }
        if (ok) {
            puts("YES");
            printf("%d %d
    ", i, j);
        } else {
            puts("NO");
        }
        
        return 0;
    }

    写得巨丑, 有空重写一发吧.

  • 相关阅读:
    中心极限定理
    BCEloss和交叉熵损失的区别
    postgresql的python接口
    DataGrip 2020.1 安装与激活方法
    区块链技术
    TensorRT推理加速推断并提高吞吐量
    纯视觉取代slam做路径规划及避障的思路
    DL重新回顾总结
    OpenCV 轮廓方向
    OpenCV 低通滤波(可设置频率)
  • 原文地址:https://www.cnblogs.com/ichn/p/8024838.html
Copyright © 2020-2023  润新知