zoukankan      html  css  js  c++  java
  • 2020杭电HDU-6759多校第一场Leading Robots(贪心+栈的运用)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6759

    Problem Description

    Sandy likes to play with robots. He is going to organize a running competition between his robots. And he is going to give some presents to the winners. Robots are arranged in a line. They have their initial position (distance from the start line) and acceleration speed. These values might be different. When the competition starts, all robots move to the right with speed: 

    Here a is acceleration speed and t is time from starting moment. 

    Now, the problem is that, how many robots can be the leader from the starting moment? 

    Here leader means the unique rightmost robot from the start line at some moment. That is, at some specific time, if a robot is rightmost and unique then it is the leading robot at that time. There can be robots with same initial position and same acceleration speed. 

    The runway is so long that you can assume there's no finish line.

    Input

    The input consists of several test cases. The first line of input consists of an integer T(1≤ T≤50), indicating the number of test cases. The first line of each test case consists of an integer N(0 < N≤ 50000), indicating the number of robots. Each of the following N lines consist of two integers: p,a (0 < p,a < 2^31) indicating a robot's position and its acceleration speed.

    Output

    For each test case, output the number of possible leading robots on a separate line.

    Sample Input

    1
    3
    1 1
    2 3
    3 2

    Sample Output

    2

    题目大意:给你每个机器人的初始位置和加速度,问你总共有多少个机器人有可能成为一次领导机器人(在最前面)。

    我们先给每个机器人的位置排序,按照位置最大的,加速度最大的优先,然后我们用栈来保存每个可能成为领导的机器人的位置,加速度和其成为领导的时间,那么很明显,在后面的机器人,如果加速度小于等于当前的机器人,那么他们是不可能成为领导人的,所以我们循环的时候可以直接continue。如果加速度大的话,那么它一定能够追上前面的机器人。

    所以接下来我们要算一下它追上前面机器人的时间,希望大家的物理都学的不错,有公式$s=v_0t+frac{1}{2}at^2$。那么它追上前面那个机器人的世界就是当他们的路程一样的时候,也就是

    $pos_{tail}-pos_i+0t+frac{1}{2}a_{tail}t^2=0t+frac{1}{2}a_it^2$

    那么为了使得我们的结果是准确的,我们将式子化为$frac{1}{2}t^2=frac{pos_{tail}-pos_i}{a_i-a_{tail}}$,那么我们不用将$t$算出来,只需要用他来比较大小,所以$frac{1}{2}t^2$完全可以代替它的,接下来我们再用分数来保存每个时间。

    然后如果当前的机器人追上栈顶机器人的时间小于等于栈顶机器人成为领导人的时间,那么我们将做出栈操作,也就是说栈顶的机器人在超越别人之前已经被人超越了。

    最后我们需要判断一下栈内是否有位置一样,加速度一样的元素,这个我们可以做个map来计数。

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int mac=5e4+10;
    
    struct node
    {
        int pos,a;
        bool operator <(const node&b)const{
            if (pos==b.pos) return a>b.a;
            return pos>b.pos;
        }
    }robots[mac];
    int stk[mac],va[mac];
    struct fenshu
    {
        int fz,fm;
        bool operator <(const fenshu &a)const{
            return (ll)fz*a.fm<(ll)fm*a.fz;
        }
        bool operator <=(const fenshu &a)const{
            return (ll)fz*a.fm<=(ll)fm*a.fz;
        }
        bool operator ==(const fenshu &a)const{
            return (ll)fz*a.fm==(ll)fm*a.fz;
        }
    }times[mac];
    
    int main(int argc, char const *argv[])
    {
        int t;
        scanf ("%d",&t);
        while (t--){
            int n;
            scanf ("%d",&n);
            map<pair<int,int>,int>mp;
            for (int i=1; i<=n; i++){
                int pos,a;
                scanf ("%d%d",&pos,&a);
                va[i]=stk[i]=0;
                mp[make_pair(pos,a)]++;
                robots[i]=node{pos,a};
            }
            sort(robots+1,robots+1+n);
            int tail=1;
            stk[tail]=robots[1].pos;
            times[tail]=fenshu{0,1};//成为领导人的时间,这里保存1/2t^2来减小误差
            va[tail]=robots[1].a;
            for (int i=2; i<=n; i++){
                if (robots[i].a<=va[tail]) continue;
                while (tail>=1 && fenshu{stk[tail]-robots[i].pos,robots[i].a-va[tail]}<=times[tail]){
                    tail--;
                } 
                times[++tail]=fenshu{stk[tail-1]-robots[i].pos,robots[i].a-va[tail-1]};
                stk[tail]=robots[i].pos;
                va[tail]=robots[i].a;
            }
            int ans=0;
            for (int i=1; i<=tail; i++){
                if (mp[make_pair(stk[i],va[i])]==1) ans++;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    linux搭建maven私服
    sgu438-The_Glorious_Karlutka_River
    [模板] 长链剖分
    bzoj3277-串
    [模板] 矩阵树定理
    [模板] 最短路/差分约束
    luogu2597-[ZJOI2012]灾难 && DAG支配树
    bzoj1150-[CTSC2007]数据备份Backup
    bzoj2152-[国家集训队]聪聪可可
    [模板] 树的重心/点分治/动态点分治
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13362733.html
Copyright © 2011-2022 走看看