• [hdu6163]CSGO


    多校第9场第3题,一场比赛3个计算几何,甘版下风。

    讲道理,看到题就知道是要转一圈,题目也规定了线段之间无相交,这也意味着以同一个点为中心,线段之间的遮挡关系是不变的,我们就可以通过维护当前角度上最近的线段,来判断某个点是否能被击中。

    维护遮挡关系,可以直接比较他们与当前角度的射线的交点,到原点的距离,这里用了一些奇怪的方法来获得这个距离(这个方法只有在确定与射线有交点后才是正确的。

    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    #include<queue>
    #include<set>
    #include<ctime>
    #include<map>
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    
    typedef long double ld;
    
    const ld eps = 1e-20;
    ld PI = acos((ld)-1.0);
    
    //#define ENABLE_FREAD
    
    struct io_s {
    
        bool negative;
        char ch;
    
        inline bool isdigitx(char c) {
            return c >= '0' && c <= '9';
        }
    
    
    #ifdef ENABLE_FREAD
        inline char nextchar() {
            static char buf[100000], *p1 = buf, *p2 = buf;
            return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
        }
    #else
        inline char nextchar() {
            return getchar();
        }
    #endif
    
        template<typename T>
        bool rn(T& _v) {
            negative = false;
            _v = 0;
            while (!isdigitx(ch = nextchar()) && ch != EOF) { negative = ch == '-'; };
            if (ch == EOF)return false;
            do {
                _v *= 10;
                _v += ch - '0';
            } while (isdigitx(ch = nextchar()));
            if (negative) _v = -_v;
            return true;
        }
    
        template<typename T>
        bool run(T& _v) {
            _v = 0;
            while (!isdigitx(ch = nextchar()) && ch != EOF) {};
            if (ch == EOF)return false;
            do {
                _v *= 10;
                _v += ch - '0';
            } while (isdigitx(ch = nextchar()));
            return true;
        }
    
        template<typename T>
        inline T r() {
            T v = T();
            rn(v);
            return v;
        }
    
        inline int ri() { return r<int>(); }
        inline ll rll() { return r<ll>(); }
    
        inline int gets(char* s) {
            return gets(s, '');
            /*
            char* c = s;
            do {
            ch = nextchar();
            } while (ch == '
    ' || ch == '
    ');
            do {
            *(c++) = ch;
            ch = nextchar();
            } while (ch != '
    ' && ch != '
    ');
            *(c++) = '';
            return c - s - 1;
            */
        }
    
        inline int gets(char* s, char base) {
            char* c = s;
            do {
                ch = nextchar();
            } while (ch == '
    ' || ch == '
    ');
            do {
                *(c++) = ch - base;
                ch = nextchar();
            } while (ch != '
    ' && ch != '
    ');
            *(c++) = '';
            return c - s - 1;
        }
    
        inline char get() {
            do {
                ch = nextchar();
            } while (ch <'A' || ch >'Z');
            return ch;
        }
    
        template<class T>
        inline void o(T p) {
            static int stk[70], tp;
            if (p == 0) { putchar('0'); return; }
            if (p < 0) { p = -p; putchar('-'); }
            while (p) stk[++tp] = p % 10, p /= 10;
            while (tp) putchar(stk[tp--] + '0');
        }
        inline void ln() { putchar('
    '); }
    
        inline void space() { putchar(' '); }
    
        template<class T>
        inline void oln(T p) {
            o(p); ln();
        }
    
    } io;
    
    int n, m, q;
    
    struct V2D {
        ll x, y;
        V2D() : x(0), y(0) {}
        V2D(ll _x, ll _y) : x(_x), y(_y) {}
    
        inline double acos() const {
            return atan2(y, x);
        }
    
        inline ll len2() const {
            return x*x + y*y;
        }
    
        inline ld len() const {
            return sqrt(len2());
        }
    
        inline V2D operator *(const ll q) const {
            return V2D(x*q, y*q);
        }
    
        inline ll operator ^(const V2D q) const {
            return x*q.y - y*q.x;
        }
    
        inline ll operator *(const V2D q) const {
            return x*q.x + y*q.y;
        }
    
        inline V2D operator +(const V2D q)const {
            return V2D(x + q.x, y + q.y);
        }
    
        inline V2D operator -(const V2D q)const {
            return V2D(x - q.x, y - q.y);
        }
    
        inline V2D operator +=(const V2D q) {
            x += q.x, y += q.y;
            return *this;
        }
    
        inline V2D operator -=(const V2D q) {
            x -= q.x, y -= q.y;
            return *this;
        }
    
        inline void read() {
            io.rn(x), io.rn(y);
        }
    };
    
    const int N = 1e4 + 10;
    const int M = N * 3;
    const int Q = 12 + 3;
    
    V2D Enemies[N];
    
    struct Wall {
        V2D a, b;
    } Walls[N];
    
    bool ap[N];
    
    V2D Base;
    V2D Lv;
    
    struct Node {
        V2D point;
        int type;
        double angle;
    } ns[M];
    
    inline ld dis(const Wall& p) {
        V2D L = p.a - p.b;
        swap(L.x, L.y);
        L.y = -L.y;
        return abs(p.a*L) * Lv.len() / abs(L*Lv);
        //return abs(p.a*L) / abs(L*Lv) * Lv.len();
        //ld v = abs(p.a*L) / L.len();
        //ld v2 = abs(L*Lv) / Lv.len() * v / L.len();
        //printf("%.4Lf: %.4Lf!
    ", v, v2);
        //return v * v / v2;
    }
    
    class WallComp
    {
    public:
        inline bool operator()(const int& left, const int& right) const
        {
            double dx = dis(Walls[left]);
            double dy = dis(Walls[right]);
            return dx < dy;
        }
    };
    
    set<int, WallComp> s;
    
    inline bool equal(double x, double y) {
        return fabs(x - y) < eps;
    }
    
    inline bool cmp(const Node &x, const Node &y) {
        return equal(x.angle, y.angle) ? x.type > y.type : x.angle < y.angle;
    }
    
    int ct = 0;
    
    inline Node& AddNode(V2D v, int t) {
        Node &p = ns[ct++];
        p.point = v;
        p.angle = v.acos();
        p.type = t;
        return p;
    }
    
    int main() {
        int T = 0;
        while (io.rn(n) && io.rn(m) && io.rn(q)) {
            printf("Case #%d:
    ", ++T);
            for (int i = 1; i <= n; ++i) Enemies[i].read();
            for (int i = 1; i <= m; ++i)
                Walls[i].a.read(), Walls[i].b.read();
    
            queue<int> ready_to;
            while (q--) {
                s.clear();
                memset(ap, 0, sizeof(ap));
                Base.read();
                ct = 0;
    
                for (int i = 1; i <= n; ++i)
                    Enemies[i] -= Base;
                for (int i = 1; i <= m; ++i)
                    Walls[i].a -= Base, Walls[i].b -= Base;
    
                for (int i = 1; i <= n; ++i) {
                    AddNode(Enemies[i], 0);
                }
                Lv = V2D(-1, 0);
                ll dx = -1e9;
                for (int i = 1; i <= m; ++i) {
                    AddNode(Walls[i].a, i);
                    AddNode(Walls[i].b, i);
                    V2D a = Walls[i].a;
                    V2D b = Walls[i].b;
                    if (min(a.y, b.y) >= 0)continue;
                    if (max(a.y, b.y) < 0)continue;
                    if (max(a.y, b.y) == 0) {
                        if (a.y == 0 && a.x < 0) {
                            s.insert(i);
                            ap[i] = true;
                            continue;
                        }
                        if (b.y == 0 && b.x < 0) {
                            s.insert(i);
                            ap[i] = true;
                            continue;
                        }
                        continue;
                    }
                    double dx = 1.0 * (abs(a.y)*b.x + abs(b.y)*a.x) / (abs(a.y) + abs(b.y));
                    if (dx < 0) {
                        s.insert(i); ap[i] = true;
                    }
                }
                sort(ns, ns + ct, cmp);
    
                int cur = 0, ans = 0;
                while (cur < ct) {
                    Lv = ns[cur].point;
                    double now = ns[cur].angle;
                    ld dx = 1e9;
                    bool flag = false;
                    while (cur < ct) {
                        if (fabs(ns[cur].angle - now) > eps)break;
                        if (ns[cur].type == 0) {
                            if (!flag) {
                                flag = true;
                                if (s.size() > 0) dx = min(dx, dis(Walls[*s.begin()]));
                            }
                            ld d = ns[cur].point.len();
                            if (d < dx)++ans;
                            ++cur;
                            continue;
                        }
                        int t = ns[cur].type;
                        if (cur + 1 < ct && fabs(ns[cur + 1].angle - now) < eps && ns[cur + 1].type == t) {
                            dx = min(dx, min(ns[cur].point.len(), ns[cur + 1].point.len()));
                            cur += 2;
                            continue;
                        }
                        bool &x = ap[t];
                        if (x) {
                            ready_to.push(t);
                        }
                        else {
                            s.insert(t);
                        }
                        x ^= 1;
                        ++cur;
                    }
                    while (ready_to.size() > 0) {
                        s.erase(ready_to.front());
                        ready_to.pop();
                    }
                }
                io.oln(ans);
    
                for (int i = 1; i <= n; ++i)
                    Enemies[i] += Base;
                for (int i = 1; i <= m; ++i)
                    Walls[i].a += Base, Walls[i].b += Base;
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    Serverless 时代下大规模微服务应用运维的最佳实践
    Dubbo 跨语言调用神兽:dubbo-go-pixiu
    Flink 1.12 资源管理新特性回顾
    [JDBC] Kettle on MaxCompute 使用指南
    AI运动:阿里体育端智能最佳实践
    MaxCompute非事务表如何更新数据
    如何利用云原生技术构建现代化应用
    实时数仓入门训练营:实时计算 Flink 版 SQL 实践
    实时数仓入门训练营:基于 Apache Flink + Hologres 的实时推荐系统架构解析
    Flink + Iceberg + 对象存储,构建数据湖方案
  • 原文地址:https://www.cnblogs.com/kblack/p/7517676.html
Copyright © 2020-2023  润新知