zoukankan      html  css  js  c++  java
  • Leading Robots

    Leading Robots

    题意:给了(n)个机器人的初始位置(p)和加速度(a),起始速度都是(0),问起跑后,问你有多少个机器人当过第一名,即在某一时刻,有唯一一个机器人如果冲在最前面则他是当过第一名的,注意并列第一则不算第一,赛道是无限长的。

    大佬题解:here

    AC_Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<map>
     6 #include<iostream>
     7 using namespace std;
     8 typedef long long ll;
     9 #define endl '
    '
    10 const int maxn = 5e4+5;
    11 const int inf = 0x3f3f3f3f;
    12 
    13 struct node{
    14     ll pi,ai;
    15 }a[maxn],st[maxn],c[maxn];
    16 //st为手写模拟栈
    17 
    18 int n;
    19 bool cmp(node x, node y){
    20     if( x.ai==y.ai ) return x.pi>y.pi;
    21     return x.ai>y.ai;
    22 }
    23 
    24 bool judge(node x, node y, node z){//判断方法就是求抛物线的交点
    25     ll p1=2*(y.pi-x.pi);
    26     ll a1=1*(x.ai-y.ai);
    27     ll p2=2*(z.pi-y.pi);
    28     ll a2=1*(y.ai-z.ai);
    29     return p1*a2<=p2*a1;//p1/a1<=p2/a2
    30 }
    31 
    32 int main()
    33 {
    34     int T;
    35     scanf("%d",&T);
    36     while( T-- ){
    37         map<ll, map<ll,ll> >mp;
    38         scanf("%d",&n);
    39         for(int i=1;i<=n;i++){
    40             scanf("%lld%lld",&a[i].pi,&a[i].ai);
    41             mp[a[i].pi][a[i].ai]++;
    42         }
    43         sort(a+1,a+1+n,cmp);
    44 
    45         /****************************************/
    46         //以下这一段是为了找可能在最前面的车,排除了一些不可能的车
    47         //怎么排出的呢?
    48         //我们首先是按照加速度从大到小排了序,如果加速度相同的话,那么按照初始位置从大到小排个序
    49         //那么你加速度又小,初始位置也小的话,那就明显不可能冲到最前面了呀
    50         //这一段我也是在比赛时想到了,然后后面就一直在想抛物线交点的问题,没有想到巧妙地运用栈,然后被交点问题越缠越乱也就没有想出来(太弱了......)
    51         /***************************************/
    52         int h=1;
    53         st[h]=a[1];
    54         ll mx=a[1].pi;
    55         for(int i=2;i<=n;i++){
    56             if( a[i].pi>mx ){
    57                 mx=a[i].pi;
    58                 st[++h]=a[i];
    59             }
    60         }
    61 
    62         /***************************************/
    63         //然后进行第二步排除:也就是根据谁先交,交谁来排除
    64         //首先0位置在最前面的是一定可以冲在最前面的(也不一定哈,毕竟两人并列的不算,不过这个我们姑且认为他们就是第一,后面在删了他们就好了)
    65         //注意这里我们按照加速度从小到大来了,这样好排除些(大佬的思路,我的脑子转不过来,没有想到......)
    66         //用一个栈存取可能为第一名的机器人,如果栈中的机器人小于2个,就直接加入,因为只有两个人,加速度大的,在无限长的路上,最后一定会冲到前面
    67         //否则如果第i个机器人超过次栈顶机器人的时间,小于等于栈顶机器人超过次栈顶机器人的时间,那么栈顶机器人其实是不会有机会单独冲到最前面的(如图1,2),这时我们就抛出栈顶,然后这样一直检验就好了
    68         /***************************************/
    69         int k=1;
    70         c[1]=st[h];
    71         for(int i=h-1;i>=1;i--){//倒着来,相当于按加速度从小到大排序了
    72             if( k<=1 ){
    73                 c[++k]=st[i];
    74                 continue;
    75             }
    76             while( k>=2 ){
    77                 if( judge(st[i],c[k],c[k-1])) {
    78                     k--;
    79                 }else{
    80                     break;
    81                 }
    82             }
    83             c[++k]=st[i];
    84         }
    85 
    86         /************************************/
    87         //终于到了最后一步排除了,排除并列的人
    88         //上代码就直接理解了
    89         /************************************/
    90         int ans=0;
    91         for(int i=1;i<=k;i++){
    92             if( mp[c[i].pi][c[i].ai]==1 ){
    93                 ans++;
    94             }
    95         }
    96         printf("%d
    ",ans);
    97     }
    98     return 0;
    99 }
  • 相关阅读:
    js 对象数组 排序
    sql 时间条件查询
    idea和Pycharm 等系列产品激活激活方法和激活码 100 年
    开源协议简介
    面试题
    VIM|基础命令
    git|基础命令
    VIM|复制
    lua|基础教程
    Printf格式输出详解
  • 原文地址:https://www.cnblogs.com/wsy107316/p/13378558.html
Copyright © 2011-2022 走看看