跑步问题。O(∩_∩)O~~

题目来源:https://biancheng.love/contest-ng/index.html#/34/problems

题目描述

最近,零崎发现自己的基友们都很闲,于是提议大家来玩一个叫“跑得快”的游戏吧,输的人就去操场跑三千米。经过一番苦战,除了跑的最快的jhljx,其他人都要去跑三千米了……

关于长跑,零崎有一个无耻的习惯,那就是紧跟着第一的人跑(如果前面没人就干脆不跑)。因为学院路这边的操场上每天都有很多人跑步锻炼身体,零崎肯定是逃不掉这个三千米的,跑完不过是时间问题。

为了简化问题,假设这些人跑步都是匀速的,零崎会跟在第一个人后面跑,如果被更快的人超过,零崎会加速跟在那个人后面。那么零崎到底多久能跑完?

输入

多组输入数据。

每组输入数据第一行为一个整数N,为操场上跑步的总人数。

接下来N行每行两个数Vi,Ti为第i个人的速度(km/h)和出发时间(s)(负数为在零崎之前出发,不考虑超过零崎一圈的情况)

每组输入数据中至少有一组出发时间非正的数据和一组出发时间非负的数据。

输出

对于每组数据,输出一行,为零崎跑完三千米的时间,以秒为单位向上取整。

输入样例

4
20 0
25 -155
27 190
32 200

输出样例

538

Hint

double ceil(double x) 头文件 math.h / cmath

解题思路:

根据题目要求,不考虑超过一圈的情况,这样可以把跑道看做一条直线。每个人都是匀速直线地跑步,而你却是跟着超过你的人跑步。当没有人在你前面的时候你会觉得没有动力所以也就站在起点一动不动,直到有人超过你。这时你就跟着这个人一起跑。突然又有一个人超过了你们两个,所以你决定追上他,跟着新的人跑。按照这个规律下去,直到到达终点。我们现在要做的就是求出到达终点也就是跑3000米需要的时间。

仔细想想,提前出发的人也就是出发时间为负值的人,我们没有必要把他们考虑进去。第一种情况:如果你能超过他,那么说明你的速度比他快也就是你能更快的到达终点,不需要跟着他,也就相当于不考虑他了。第二种情况:你没有追上先出发的那些人,说明你没有资格跟在他们后面,为什么没有资格呢,是因为后出发的人当中没有人能够超过他们,也就是你跑完3000米的时间跟他们没有关系。因此可以将出发时间为负值的那些人当做路人甲,不用管他们。

现在我们需要求出到达终点的时间。因为每次你都能跟着超过你的人,所以直到终点你一直都是最快的,(这里提示一下,你不是全程都跟着最快的人跑,你这是在路途中不断地更换最快的人),那么我们求的时间就是谁最先到达终点,你也就跟着他到达了终点。也就是意味着不用考虑跑步过程中究竟是先跟着谁然后跟着谁,决定你跑步时间的是最先到达终点的(提示一下,这里最先到达终点的所属集合是出发时间为非负数,也就是不提前出发的人)。

通过分析很容易得到代码:

#include <bits/stdc++.h>

using namespace std;
#define max_size 10000

struct Node{
double v;
double t;
double time;
};

bool cmp(Node a,Node b)
{
    return a.time<b.time;
};

Node no[max_size];

int main()
{
    int N;//总人数
    while(cin>>N)
    {
        for(int i=0;i<N;i++)
        {
            cin>>no[i].v>>no[i].t;
            no[i].v/=3.6;
            if(no[i].t<0)
                no[i].v=0.1;
                no[i].time=no[i].t+(3000.0/(no[i].v));
        }
        sort(no,no+N,cmp);
        int ans=ceil(no[0].time);
        cout<<ans<<endl;
    }
}

 

作者: 伊甸一点

本文版权归作者伊甸一点和博客园所有,欢迎转载和商用(须保留此段声明),且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.