CSP模拟赛T1 手机(awesome)

手机(awesome)

【题目描述】

三星 galaxy fold 终于发布了,作为全球第一个拿到这部手机的第三方,自如决定独享
这个 moment。手机刚刚开售,他就购买了首批所有手机,然后,他就等着快递员将手机送
货上门。自如的家和快递仓库都位于一条直线上。我们将自如的家定为零点,将这条直线看
作一条数轴,则每一个仓库都在数轴上的整点上。每一个仓库都有一个快递员同时出发,开
车前往自如的家。每个快递员开车的速度并不一样,而到自如家的路只允许并排行驶一辆车,
则当一个快递员发现前面有一辆慢车的时候,他就只能减速,紧跟那辆慢车行驶(不考虑车
身长度)。现在自如想知道,对于从每一个仓库送来的手机,将会在什么时间到达自如的手
中?

【输入】

第一行一个整数 n,表示仓库的数量
接下来 n 行,每行两个整数𝑝 𝑖 ,𝑤 𝑖 ,表示 i 号仓库的位置和从 i 号仓库出发的快递员的车
速。

【输出】

N 行,每行一个整数,表示从 i 号仓库送出的手机到达自如家的时间。
由于时间可能不是整数,输出其对 1000000007 取模的值。

【样例输入】

3
1 1
2 1
3 2

【样例输出】

1
2
2

【数据范围】

对于 30%的数据,n<=30
对于 100%的数据,n<=100000,\(\left\vert pi\right\vert \\\),𝑤𝑖 ≤ \(10^9\)

【提示】

对于分数 p/q,其对 m 取模的方式为找到一个整数 r,使得 q×r≡1(mod m),取模结果即
为 p×r (mod m)。

理解

一看这道题,就想打个大模拟,但仔细思考一下,可以很容易发现,如果一个人可以追上他前面的人,那么他们就会一起到终点!!!(划重点)

解题过程?

1.正方向和负方向分开考虑...(话说如果不这么做的话难道还把放到一起跑)
2.二者实际是一个问题,只考虑正方向(把负的变成正的在处理就行)
3.按照编号从小到大枚举每一个仓库,并且计算手机从仓库出发不考虑前方慢车到自如手中的时间。
4.考虑之前枚举到的仓库最晚到达自如手中的时间为b,刚才计算到的值为a,则当前仓库的手机到达自如手中的真实时间则为max(a,b)。(因为咱要减速)
5.时间复杂度O(n)(散花✿✿ヽ(°▽°)ノ✿)

参考代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5,mod=1e9+7;
int n;
int ans[N];
struct node {
    int p,v,id;
} t[N],g[N];
inline bool cmp(node x,node y) {
    return x.p<y.p;
}
inline int ksm(int x,int y) {
    int ans=1;
    while(y) {
        if(y&1) {
            ans=(1LL*ans*x)%mod;
        }
        x=(1LL*x*x)%mod;
        y>>=1;
    }
    return ans;
}
signed main() {
    scanf("%lld",&n);
    int e=0,b=0;
    for(int i=1; i<=n; ++i) {
        int p,v;
        scanf("%lld%lld",&p,&v);
        if(p>=0) {
            t[++e]=(node) {
                p,v,i
            };
        } else {
            g[++b]=(node) {
                -p,v,i
            };
        }
    }
    sort(t+1,t+e+1,kkk);
    double maxe=0;
    int res=0;
    for(int i=1; i<=e; ++i) {
        double now=double(t[i].p)/t[i].v;
        if(now>maxe) {
            maxe=now;
            res=(1LL*t[i].p*ksm(t[i].v,mod-2));
        }
        ans[t[i].id]=res+mod;
    }
    maxe=0,res=0;
    sort(g+1,g+b+1,kkk);
    for(int i=1; i<=b; ++i) {
        double now=double(g[i].p)/g[i].v;
        if(now>maxe) {
            maxe=now;
            res=(1LL*g[i].p*ksm(g[i].v,mod-2));
        }
        ans[g[i].id]=res+mod;
    }
    for(int i=1; i<=n; ++i) {
        printf("%lld\n",ans[i]%mod);
    }
    return 0;
}
posted @ 2019-11-12 13:49  贰冬  阅读(144)  评论(0)    收藏  举报