zoukankan      html  css  js  c++  java
  • 2020杭电多校第一场I:Leading Robots

    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 < 231) 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

     题意:给定n个人一个初始位置和一个加速度,询问在很长一段时间内,共有多少人成为某一时刻唯一的第一名。

    在时间t时,第i个人所处的位置为pi+(ai*t*t)/2.

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+9;
    const double ep=1e-7;
    const int mod=1e9+9;
    #define mk make_pair
    #define PII pair<int,int>
    #define PLL pair<ll,ll>
    #define pb push_back
    typedef long long ll;
    int sgn(double x)
    {
        if(fabs(x)<ep)return 0;
        if(x>0)return 1;return -1;
    }
    struct point{
        ll a,p;
    }p[maxn];
    bool cmp(point a,point b)
    {
        if(a.p==b.p)return a.a>b.a;
        return a.p>b.p;
    }
    vector<int>v;
    int n;
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            p[n+1].a=p[n+1].p=0;
            for(int i=1;i<=n;i++)scanf("%d%d",&p[i].p,&p[i].a);
            sort(p+1,p+1+n,cmp);//最开始时的位置排序 
            //加速度最大的那个人肯定是最后的赢家 
            ll ma=p[1].a;
            stack<PII >s;//保存是第几个称为第一名 
            s.push(mk(1,1));
            for(int i=2;i<=n;i++)
            {
                if(p[i].a<=ma)continue;
                //如果加速度小于且本来位置比较靠后的话是不可能超过前面那个人的 
                ma=p[i].a;//根据最大加速度 
                int num=1;
                while(!s.empty())
                {
                    PII pp=s.top();//前面i-1个人中是num1先超过了num2 
                    int num1=pp.first;
                    int num2=pp.second;
                    double t2=sqrt(2.0*(p[i].p-p[num1].p)/(p[num1].a-p[i].a));
                    double t1=0;
                    if(num1!=num2)
                    t1=sqrt(2.0*(p[num1].p-p[num2].p)/(p[num2].a-p[num1].a));
                    if(sgn(t2-t1)<=0)
                    {
                        num=num2;s.pop();
                        //说明在num1超过num2之前i就超过了num1
                        //说明i比num1先超过num2 
                    }
                    else
                    {
                        num=num1;break;
                    }
                }
                s.push(mk(i,num));
                //因为这个人的加速度最大,所以他在这前i个人中肯定是最后的赢家 
            } 
            int ans=s.size();
            while(!s.empty())
            {
                PII pp=s.top();s.pop();
                int num=pp.first;
                if(p[num].a==p[num+1].a&&p[num].p==p[num+1].p)ans--;
                //说明出现了不是唯一的情况 
            }
            printf("%d
    ",ans);
        }
    }
    欢迎加我qq1165750856一起玩呀~
  • 相关阅读:
    PowerDesigner 找不到Identity列的解决方法
    C# DataTable 和List之间相互转换的方法
    解决Win8无法升级.NET Framework 3.5.1 提示错误0x800F0906
    C#虚方法和抽象方法区别
    VS自带WCF测试客户端
    asp.net读取Excel数据
    输出用户的IP地址,并且判断用户的IP地址是否在192.168.1.100 --- 192.168.1.150之间
    验证电子邮箱正则表达式
    用PHP实现冒泡排序将数组$a=array()按照从小到大的方式排序
    打开a.txt文件在文件中最前面加上hello
  • 原文地址:https://www.cnblogs.com/HHHEN/p/13392100.html
Copyright © 2011-2022 走看看