【问题描述】
然而,在大洋彼岸的某 国,人们对COVID19并未引起足够重视,他们的领导人甚至对居家隔离、戴口罩以及保持社交距离等措施非常不屑,在当时疫情完全失控。
在一个风景秀丽的小镇,一天早上,有 N 名晨跑爱好者(编号 1 ~ N )沿着优雅的江边景观道朝同一方向进行晨跑,第 i 名跑者从位置 Si 处起跑, 且其速度为 Vi。换句话说,对所有的 t ≥ 0,在时刻 t 第 i 名跑者的位置为 Si + Vi ·t。
很不幸的是,其中一名跑者在 t = 0 的时刻感染了病毒,这种病毒只会在同一时刻处在同一位置的跑者之间传播,新感染了病毒的跑者也会感染其他人,很显然,等待足够长的时间,那么病毒会感染一些特定的跑者。那么,在 N 名晨跑爱好者中会有多少人感染新冠病毒?
【输入形式】
输入包含三行:
-
-
第一行包含为两个整数 N 和 K,分别表示跑者的人数以及开始时感染了病毒的跑者编号。
-
第二行包含 N 个正整数 S1、S2、...、SN,用空格隔开,分别表示跑者的起始位置。
-
第三行包含 N 个正整数 V1、V2、...、VN,用空格隔开,分别表示跑者的速度。
-
【输出形式】
输出为一个整数,表示最终被感染人数。
【样例输入】
6 3 3 9 8 5 7 5 6 6 5 4 6 3
【样例输出】
3
【样例说明】
【评分标准】
对于50%的评测用例,0< K ≤ N ≤102
对于70%的评测用例,0< K ≤ N ≤104
对于100%的评测用例,0< K ≤ N ≤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;
}