Leading Robots

Leading Robots

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

大佬题解:here

Leading Robots

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 '\n'
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\n",ans);
97     }
98     return 0;
99 }

 

上一篇:CTF-SSH私钥泄露


下一篇:python爬虫遵守规则