ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HDU多校第一场 1009.Leading Robots

2020-07-24 16:31:52  阅读:274  来源: 互联网

标签:HDU Leading 超过 t1 u1 Robots st push u2


题解思路:

首先,我们很容易知道一个点能当第一的条件是它在超过前面所有人之前不能被他后面的人超过。那么先考虑哪些点能超过前面的所有点呢?显然需要你的加速度大于前面所有点的加速度,那么我们就可以先按照位置排序,再按照加速度排,只考虑 pos1>pos2 && a1<a2 的点即可。

我们处理出这些点以后应该怎么办呢?朴素想法:枚举上述处理后的每个点,计算自己成为第一的时间t1,再计算后面的点超过自己最短的时间t2,若t1<t2,则会对答案产生贡献。思路很清晰,但是总复杂度为O(n2)。

其实在计算过程中就能意识到这里面由很多无用的计算,比如,我已经知道点3能在点2超过点1之前超过点1,也知道点4不能在点2超过点1之前超过点1,那么我就没必要去计算点3、点4谁能先超过点2,我个人觉得这个逻辑还是比较好理解的。但是在朴素算法中这些无用的计算都存在。那么我们应该怎样取优化它呢?

优化算法:利用栈后进先出的性质,对n从前往后枚举,每次比较时取栈顶两个点u1、u2,若 t(u1->u2)<t(i ->u2)则说明当前点i不能在u1到达u2前到达u2,因此push(i),点i成为新的栈顶;若 t(u1->u2)>=t(i ->u2)则说明当前点i能在u1到达u2前到达u2,因此pop(u1),因为u1能被点i超过,不可能成为第一,然后对栈内元素继续如上所述操作下去。


对上述算法没那么理解的可以看一下我的代码。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
#define endl '\n'
#define p4 puts("444")
const int MAXN = 1e5+10;
const double Pi = acos(-1.0);
const ll mod = 1e9+7;

int n,m;
struct node{
    ll p,a;
    int vis;
}r[MAXN],R[MAXN];
bool cmp(node aa,node bb){
    if(aa.p!=bb.p)return aa.p>bb.p;
    else return aa.a>bb.a;
}

void solve(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld %lld",&r[i].p,&r[i].a);
    sort(r+1,r+n+1,cmp);
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(R[cnt].a==r[i].a&&R[cnt].p==r[i].p)R[cnt].vis=1;
        if(R[cnt].a<r[i].a){
            cnt++;
            R[cnt].a=r[i].a;
            R[cnt].p=r[i].p;
            R[cnt].vis=0;
        }
    }
    n=cnt;
    stack<node>st;
    st.push(R[1]);
    if(n>1)st.push(R[2]);
    for(int i=3;i<=n;i++){
        while(st.size()>=2){
            node u2=st.top();st.pop();
            node u1=st.top();
            ll t1=(u1.p-R[i].p)*(u2.a-u1.a);
            ll t2=(u1.p-u2.p)*(R[i].a-u1.a);
            if(t1>t2){
                st.push(u2);
                break;
            }
        }
        st.push(R[i]);
    }
    int ans=0;
    while(!st.empty()){
        node u=st.top();st.pop();
        ans+=(u.vis^1);
    }
    cout<<ans<<endl;
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--) solve();
}

 

标签:HDU,Leading,超过,t1,u1,Robots,st,push,u2
来源: https://www.cnblogs.com/Mmasker/p/13372652.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有