• poj 2274 The Race 最小堆


    题目链接

    题目大意:

    给n个小车, 每个小车有一个初始位置x和初始速度v, 保证x1 < x2..... 思路: 第一问显然就是一个逆序数, 因为v<100, 所以暴力统计就可以了。
    第二问, 我们通过观察可以得出一个性质, 超车总是先发生在相邻的两辆车。 比如a, b, c三个车, 如果他们的速度是va > vc > vb, 那么超车肯定是a超过b, 然后才能超过c。 a不可能直接不通过b就超过c。 有了这个性质, 我们可以先将所有相邻的可能发生的超车情况放入一个优先队列。 队列里的元素有4个值, 超车的时间, 超车发生的坐标, 超车的两辆车的编号。 然后初始的时候记录一下每个车前面的车的坐标以及后面的坐标。 初始就是i-1和i+1。 然后如果发生超车, 比如初始是 1, 2, 3, 4。 然后2超过3, 变成1, 3, 2, 4。 每辆车的前后坐标也要改变。 初始pre[2] = 1, nxt[2] = 3,超车之后变成pre[2] = 3, nxt[2] = 4。大概就是这样。 同时1, 3, 4也都会发生改变。 然后每次超车之后, 在将新的可能发生的超车加入队列。 然后这么不断循环。直到队列空或者10000个。 还有一种就是 a, b, c 三个车, va > vb > vc, 然后初始将a超过b, b超过c的情况放入了队列, 这时候b超过了c, 然后将a超过c的情况放入队列。然后a超过c, 再次将a超过b的情况放入队列。如果不判断一下的话就会将a超过b的情况计算两次。 判断的方法, 我是这样的。 比如两辆车a,b。 看nxt[a]是否等于b以及pre[b] 是否等于a, 如果不等于直接continue。

    具体的可以看看代码自己想一下... 真是写了好久。

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <complex>
    #include <cmath>
    #include <map>
    #include <set>
    #include <string>
    #include <queue>
    #include <stack>
    #include <bitset>
    using namespace std;
    #define pb(x) push_back(x)
    #define ll long long
    #define mk(x, y) make_pair(x, y)
    #define mem(a) memset(a, 0, sizeof(a))
    #define fi first
    #define se second
    typedef pair<int, int> pll;
    const double eps = 1e-8;
    const int maxn = 250005;
    int cnt[100], pre[maxn], nxt[maxn];
    double v[maxn], x[maxn];
    struct node
    {
        double t, pos;
        int car1, car2;
        node(){}
        node(double t, double pos, int car1, int car2):t(t), pos(pos), car1(car1), car2(car2){}
        bool operator < (node a) const
        {
            if(fabs(t - a.t)<eps) {
                return pos > a.pos;
            }
            return t > a.t;
        }
    };
    vector <pll> ans;
    int main()
    {
        int n;
        while(cin>>n) {
            priority_queue <node> q;
            ans.clear();
            mem(cnt);
            mem(pre);
            mem(nxt);
            int sum = 0;
            for(int i = 1; i <= n; i++) {
                scanf("%lf%lf", &x[i], &v[i]);
                nxt[i] = i+1;
                pre[i] = i-1;
                cnt[(int)v[i]]++;
                for(int j = v[i]+1; j < 100; j++) {
                    sum += cnt[j];
                    sum %= 1000000;
                }
            }
            for(int i = 1; i < n; i++) {
                if(v[i] > v[i+1]) {
                    double t = 1.0*(x[i+1]-x[i])/(v[i]-v[i+1]);
                    q.push(node(t, t*v[i]+x[i], i, i+1));
                }
            }
            int num = 10000;
            while(num && !q.empty()) {
                node tmp = q.top(); q.pop();
                int fi = tmp.car1, se = tmp.car2;
                if(nxt[fi] != se || pre[se] != fi)
                    continue;
                ans.pb(mk(fi, se));
                nxt[fi] = nxt[se];
                pre[se] = pre[fi];
                nxt[se] = fi;
                pre[fi] = se;
                nxt[pre[se]] = se;
                pre[nxt[fi]] = fi;
                if(pre[se] && v[pre[se]] > v[se]) {
                    double t = (tmp.pos - v[pre[se]]*tmp.t-x[pre[se]])/(v[pre[se]] - v[se]);
                    q.push(node(tmp.t + t, tmp.pos + v[se]*t, pre[se], se));
                }
                if(nxt[fi] != n+1 && v[fi] > v[nxt[fi]]) {
                    double t = 1.0*(x[nxt[fi]] + v[nxt[fi]]*tmp.t - tmp.pos)/(v[fi] - v[nxt[fi]]);
                    q.push(node(tmp.t+t, tmp.pos + v[fi]*t, fi, nxt[fi]));
                }
                num--;
            }
            cout<<sum<<endl;
            for(int i = 0; i < ans.size(); i++) {
                printf("%d %d
    ", ans[i].fi, ans[i].se);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    博客的不少图都挂了
    Xilinx EDK "ERROR:Xst:2647
    Xilinx ISE Isim仿真错误的解决方法
    LabVIEW 三维机器人展示
    放弃使用Chrome浏览器(包括360极速浏览器等)的自动密码保存功能吧 我来把密码显示给你看
    安卓手机与PC不得不说的那些事 之 篇一 网络分享
    (MCCDAQ)USB 1208 坑爹的螺丝端子设计
    Xilinx ZedBoard Run Xilinux
    VMPlayer 安装 Ubuntu 12.04 一个注意点
    【C++】判断一个图是否有环 无向图 有向图(转载)
  • 原文地址:https://www.cnblogs.com/yohaha/p/5589494.html
Copyright © 2020-2023  润新知