【CodeForces】9B-Running Student

Question

Description

小明在公交车始发站上车,他应该在哪个站点下车才能最快到达学校?如果这样的站点存在多个选择距离学校最近的站点。

  • 公交车始发站位置\((0,0)\),并且以恒定的速度\(v_b\)沿着\(X\)轴正向行驶
  • 公交车有\(n\)个站点,每个站点的坐标不同,第\(i\)个站点的坐标是\((x_i,0)\)
  • 公交车在站点的停靠时间可以忽略
  • 学校的位置\((x_u,y_u)\)
  • 小明从站点下车后跑向学校的速度是\(v_s\)
  • 两点之间的距离通过欧式距离计算
  • 小明已经在公交车上了,所以他不能在第一个公交站下车
  • 小明的速度有可能比公交车的速度快

Input

第一行包含三个整数:\(2 \leq n \leq 100\)\(1 \leq v_b,v_s \leq 1000\)。第二行是\(n\)个递增的非负整数,\(x_i\)表示第\(i\)个站点的坐标,其中\(x_1\)肯定等于0并且\(x_n \leq 10^5\)。第三行两个整数表示学校的位置\(x_u,y_u\),绝对值不超过\(10^5\)

Output

最优站点的序号

Solution

目标是\(min(\frac{s_b}{v_b} + \frac{s_s}{v_s})\),其中公交车行驶距离\(s_b\)一直在增加,小明走的距离\(s_s\)一直在减少。如果\(v_b \leq v_s\),则越早下车到达学校越快,所以这时的结果是2;否则无法直接判断在哪里下车(并不是离学校越近越好)。一开始一直希望能够找到一种比\(O(n)\)更好的解法,但是这个题只能暴力求解。

784062-20181207152355127-498591402.png%0A

解法1

# Python
# hypot()用于计算欧式距离
# min(list)可以得到list中的最小元素
# list中的元素是tuple(耗时, 距离, 编号)
# min会首先比较耗时,然后比较距离
from math import *
n, vb, vs = map(int, input().split())
d = list(map(int, input().split()))
xu, yu = map(int, input().split())
print(min([(d[i]/vb+hypot(xu-d[i], yu)/vs, hypot(xu-d[i], yu), i+1) for i in range(1, len(d))])[2])
# 还可以使用 for i, x in enumerate(d[1:]), 其中i从0开始, 结果是i+2
// C++
// 注意int类型会溢出
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
    double n, vb, vs, tmp, xu, yu;
    vector<double> d;
    cin >> n >> vb >> vs;
    for (int i = 0; i < n; i++) {
        cin >> tmp;
        d.push_back(tmp);
    }
    cin >> xu >> yu;
    double min_distance = sqrt((xu - d[1]) * (xu - d[1]) + yu * yu), min_time = d[1]/vb + min_distance/vs, index = 2;
    for (int i = 2; i < n; i++) {
        double distance = sqrt((xu - d[i]) * (xu - d[i]) + yu * yu);
        double time = (d[i]/vb + distance/vs);
        if (time < min_time) {
            min_time = time;
            min_distance = distance;
            index = i + 1;
        }
        else if (time == min_time && distance < min_distance) {
            min_distance = distance;
            index = i + 1;
        }
    }
    cout << index << endl;
    return 0;
}

转载于:https://www.cnblogs.com/cling-cling/p/10083122.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值