zoukankan      html  css  js  c++  java
  • HDU

    题意

    给定长l的环上的n个人,每个人有给不相同的速度和位置,相遇时编号大的存活,问最后留存一个人时的时间

    做法

    直接用堆来模拟即可

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    
    struct Frac {
        LL fz, fm;
        Frac() {}
        template<class T> Frac(T a):fz(a), fm(1) {}
        template<class T> Frac(T a, T b):fz(a), fm(b) {}
        Frac norm() {
            if (fz < 0 && fm < 0)
                fz = -fz, fm = -fm;
            return Frac(fz, fm);
        }
        Frac operator + (Frac rhs) {
            return Frac(fz * rhs.fm + fm * rhs.fz, rhs.fm * fm).norm();
        }
        Frac operator - (Frac rhs) {
            return Frac(fz * rhs.fm - fm * rhs.fz, rhs.fm * fm).norm();
        }
        Frac operator * (Frac rhs) {
            return Frac(fz * rhs.fz, fm * rhs.fm).norm();
        }
        Frac operator / (Frac rhs) {
            return Frac(fz * rhs.fm, fm * rhs.fz).norm();
        }
    };
    Frac operator - (int a, Frac b) {
        return Frac(a) - b;
    }
    Frac operator + (int a, Frac b) {
        return Frac(a) + b;
    }
    Frac operator / (int a, Frac b) {
        return Frac(a) / b;
    }
    bool operator < (const Frac&a, const Frac&b) {
        return a.fz * b.fm < a.fm * b.fz;
    }
    bool operator > (const Frac&a, const Frac&b) {
        return a.fz * b.fm > a.fm * b.fz;
    }
    bool operator <= (const Frac&a, const Frac&b) {
        return a.fz * b.fm <= a.fm * b.fz;
    }
    
    ostream& operator << (ostream&os, Frac a) {
        LL d = __gcd(a.fz, a.fm);
        return os << (a.fz / d) << '/' << (a.fm / d);
    }
    istream& operator >> (istream&is, Frac&a) {
        LL d;
        is >> d;
        a = d;
        return is;
    }
    
    
    const int N = 1e5 + 100;
    
    int n, l;
    struct Ant {
        int id;
        Frac p, v;
        bool operator < (const Ant&rhs) const {
            return p < rhs.p;
        }
    } a[N];
    
    struct Node {
        Node *suc, *pre;
        Ant* a;
    } nd[N];
    
    
    struct Info {
        Frac tim;
        Node *a, *b;
        Info() {}
        Info(Frac tim, Node*a, Node*b):tim(tim), a(a), b(b) {}
        bool operator < (const Info&rhs) const {
            return tim > rhs.tim;
        }
    };
    priority_queue<Info> pq;
    bool del[N];
    
    Frac getTime(Ant a, Ant b) {
        Frac v = b.v - a.v;
        Frac d = b.p - a.p;
        if (d < 0)
            d = d + l;
        if (v > 0) {
            d = l - d;
        } else d = 0 - d;
        return d / v;
    }
    
    int main() {
    #ifdef lol
        freopen("d.in", "r", stdin);
        freopen("d.out", "w", stdout);
    #endif
    
        ios_base::sync_with_stdio(false);
        cin.tie(0);
        int T; cin >> T;
        while (T--) {
            cin >> n >> l;
            for (int i = 1; i <= n; ++i)
                cin >> a[i].p;
            for (int i = 1; i <= n; ++i) {
                cin >> a[i].v;
                a[i].id = i;
            }
            sort(a + 1, a + n + 1);
    
            while (!pq.empty()) pq.pop();
            memset(del, 0, sizeof del);
    
            for (int i = 2; i <= n; ++i) {
                nd[i].pre = &nd[i - 1];
                nd[i - 1].suc = &nd[i];
                nd[i].a = &a[i];
                pq.push(Info(getTime(a[i - 1], a[i]), &nd[i - 1], &nd[i]));
            }
            nd[1].pre = &nd[n];
            nd[n].suc = &nd[1];
            nd[1].a = &a[1];
            pq.push(Info(getTime(a[n], a[1]), &nd[n], &nd[1]));
            Frac ans = 0;
            while (!pq.empty()) {
                Info u = pq.top();
                pq.pop();
                if (del[u.a->a->id] || del[u.b->a->id])
                    continue;
                if (u.a->a->id == u.b->a->id) break;
                ans = max(ans, u.tim);
                if (u.a->a->id > u.b->a->id) {
                    del[u.b->a->id] = true;
                    u.b->suc->pre = u.a;
                    u.a->suc = u.b->suc;
                    pq.push(Info(getTime(*u.a->a, *u.a->suc->a), u.a, u.a->suc));
                } else {
                    del[u.a->a->id] = true;
                    u.a->pre->suc = u.b;
                    u.b->pre = u.a->pre;
                    pq.push(Info(getTime(*u.b->pre->a, *u.b->a), u.b->pre, u.b));
                }
            }
            cout << ans << endl;
        }
    
        return 0;
    }
  • 相关阅读:
    linux 命令——19 find (转)
    linux 命令——18 locate (转)
    linux 命令——17 whereis(转)
    linux 命令——16 which(转)
    linux 命令——15 tail (转)
    linux 命令——14 head (转)
    Java for LeetCode 038 Count and Say
    Java for LeetCode 037 Sudoku Solver
    Java for LeetCode 036 Valid Sudoku
    Java for LeetCode 035 Search Insert Position
  • 原文地址:https://www.cnblogs.com/ichn/p/7400249.html
Copyright © 2011-2022 走看看