实验七 算法编程题2. 新型冠状病毒(COVID19)传播

【问题描述】

       然而,在大洋彼岸的某 国,人们对COVID19并未引起足够重视,他们的领导人甚至对居家隔离、戴口罩以及保持社交距离等措施非常不屑,在当时疫情完全失控。

       在一个风景秀丽的小镇,一天早上,有 N 名晨跑爱好者(编号 1 ~ N )沿着优雅的江边景观道朝同一方向进行晨跑,第 i 名跑者从位置 Si 处起跑, 且其速度为 Vi。换句话说,对所有的 t ≥ 0,在时刻 t 第 i 名跑者的位置为 Si + Vi ·t。 

       很不幸的是,其中一名跑者在 t = 0 的时刻感染了病毒,这种病毒只会在同一时刻处在同一位置的跑者之间传播,新感染了病毒的跑者也会感染其他人,很显然,等待足够长的时间,那么病毒会感染一些特定的跑者。那么,在 N 名晨跑爱好者中会有多少人感染新冠病毒?

【输入形式】

        输入包含三行:

    •  第一行包含为两个整数 N 和 K,分别表示跑者的人数以及开始时感染了病毒的跑者编号。

    •  第二行包含 个正整数 S1、S2、...、SN,用空格隔开,分别表示跑者的起始位置。

    •  第三行包含 个正整数 V1、V2、...、VN,用空格隔开,分别表示跑者的速度。

【输出形式】

         输出为一个整数,表示最终被感染人数。

【样例输入】

6 3
3 9 8 5 7 5
6 6 5 4 6 3

【样例输出】

3

【样例说明】
【评分标准】

     对于50%的评测用例,0< K ≤ ≤102

     对于70%的评测用例,0< ≤ ≤104

     对于100%的评测用例,0< ≤ ≤106 

【思路分析】

这是一个贪心的问题,此题中时间可看做是无限久的,那么有两种情况

  • 速度快但起始位置小,那么他有可能会追上其它人
  • 速度慢但起始位置大,那么他有可能会被其它人追上

看起来只需要记录最小速度的和最大速度的就行了。但是还有一个问题,假如速度很快的人追上了一个速度很慢的人,而这个速度很慢的人的速度比已经记录的最小速度还慢,那么此时我们久需要更新数据了。可我们怎么判断呢?最正规的做法肯定是先sort排序,但是我们可以通过多循环几次来完成这个过程,因为sort排序太耗时了,而我们需要判断的这种情况概率很低,通常2~3次即可。这样,我们可以将时间复杂度从O(nlogn)降至O(n)。

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

vector<vector<int>> runner(1000001,vector<int>(2));

int main() {
    int n, k, minSpeed,maxSpeed, res = 0;
    cin >> n >> k;
    for (int i = 1; i <= n; ++i) {
        cin >> runner[i][0];
    }
    for (int i = 1; i <= n; ++i) {
        cin >> runner[i][1];
    }
    minSpeed = maxSpeed = runner[k][1];
    for (int i = 1; i <= n; i++) {
        if (runner[i][1] > minSpeed && runner[i][0] < runner[k][0]){
            maxSpeed = max(runner[i][1], maxSpeed);
        }
        if (runner[i][1] < maxSpeed && runner[i][0] > runner[k][0]){
            minSpeed = min(runner[i][1],minSpeed);
        }
        if (runner[i][0] == runner[k][0]){//起始位置一样,都被感染
            if (runner[i][1] > minSpeed) {
                maxSpeed = max(runner[i][1], maxSpeed);
            }
            if (runner[i][1] < maxSpeed) {
                minSpeed = min(runner[i][1],minSpeed);
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        if (runner[i][1] > minSpeed && runner[i][0] < runner[k][0]){
            maxSpeed = max(runner[i][1], maxSpeed);
        }
        if (runner[i][1] < maxSpeed && runner[i][0] > runner[k][0]){
            minSpeed = min(runner[i][1],minSpeed);
        }
        if (runner[i][0] == runner[k][0]){
            if (runner[i][1] > minSpeed) {
                maxSpeed = max(runner[i][1], maxSpeed);
            }
            if (runner[i][1] < maxSpeed) {
                minSpeed = min(runner[i][1],minSpeed);
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        if (runner[i][1] > minSpeed && runner[i][0] < runner[k][0]){
            res++;
            maxSpeed = max(runner[i][1], maxSpeed);
        }
        if (runner[i][1] < maxSpeed && runner[i][0] > runner[k][0]){
            res++;
            minSpeed = min(runner[i][1],minSpeed);
        }
        if (runner[i][0] == runner[k][0]){
            if (runner[i][1] > minSpeed) maxSpeed = max(runner[i][1], maxSpeed);
            if (runner[i][1] < maxSpeed) minSpeed = min(runner[i][1],minSpeed);
            res++;
        }
    }//此处我重复循环了3次
    cout << res;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值