【问题描述】
在一个风景秀丽的小镇,一天早上,有 N 名晨跑爱好者(编号 1 ~ N )沿着优雅的江边景观道朝同一方向进行晨跑,第 i 名跑者从位置 Si 处起跑, 且其速度为 Vi。换句话说,对所有的实数 t ≥ 0,在时刻 t 时第 i 名跑者的位置为 Si + Vi ·t。
很不幸的是,其中一名跑者在 t = 0 的时刻感染了病毒,且是无症状感染者,这种病毒只会在同一时刻处在同一位置的跑者之间传播,新感染了病毒的跑者也会感染其他人,很显然,等待足够长的时间,那么病毒会感染 一些特定的跑者。
事后发现其中有一名跑者感染了病毒,如果此人就是在 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
对于90%的评测用例,0< K ≤ N ≤106
对于100%的评测用例,0< K ≤ N ≤107
逆向思考:找到不被感染的人,与总人数相减后得到被感染人数
大量输入数据时,可考虑使用scanf代替cin流输入提速
#define _CRT_SECURE_NO_WARNINGS 1//去掉这句在vs中使用scanf有时会报一些神奇的错误
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
struct People
{
int s = 0;
int v = 0;
int id = 0;//编号
};
bool cmp(People a, People b)
{
return a.s < b.s;//按照空间位置s排序
}
int n = 0, k = 0;
vector<People> people(10000001);
int main()
{
int maxlv = -1;
int minrv = INT_MAX;
//找初始感染者左边的最大速度,右边的最小速度
scanf("%d %d", &n, &k);
//cin >> n >> k;,使用cin可能超时,使用scanf在cg提交对比可提速将近0.85s
for (int i = 0; i < n; i++)
{
scanf("%d", &people[i].s);
//cin >> people[i].s;
people[i].id = i + 1;//编号
}
for (int i = 0; i < n; i++)
scanf("%d", &people[i].v);
//cin >> people[i].v;
stable_sort(people.begin(), people.begin()+n, cmp);
int mid = 0;//以初始感染者为轴
for (int i = 0; i < n; i++)
{
if (people[i].v > maxlv)
maxlv = people[i].v;//找到左边的最大速度
if (people[i].id == k)
{
mid = i;
break;
}
}
for (int i = mid; i < n; i++)
{
if (people[i].v < minrv)
minrv = people[i].v;//找到右边的最小值
}
//在初始感染者左边且速度小于右边的最小速度,不会追上感染者,安全
//在初始感染者右边且速度大于左边的最小速度,不会被感染者追上,安全
int safe = 0;
for (int i = 0; i < n; i++)
{
if (i < mid && people[i].v <= minrv&&people[i].s<people[mid].s)
safe++;
else if (i > mid && people[i].v >= maxlv && people[i].s > people[mid].s)
safe++;
}
cout << n - safe;//感染者等于全部减去未感染者
return 0;
}