【问题描述】
在一个风景秀丽的小镇,一天早上,有 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 ≤10^2
对于70%的评测用例,0< K ≤ N ≤10^4
对于90%的评测用例,0< K ≤ N ≤10^6
对于100%的评测用例,0< K ≤ N ≤10^7
思路
首先,最基本的输入没有问题吧,你也可以不开动态数组,都随便的哈
int n, k;
cin >> n >> k;
int* s = new int[n+1];
for (int i = 1; i < n + 1; i++)
{
cin >> s[i];
}
int* v = new int[n+1];
for (int j = 1; j < n + 1; j++)
{
cin >> v[j];
}
然后,就到了判断环节
–
分为两次判断
第一次是倒霉蛋,一开始就和感染者在一个位置,还要判断一定会被感染的人
int sum = 0;//记录感染者总数
//一定会被感染的人
for (int i = 1; i <= n; i++)
{
//位置在感染者后面但是速度快或者在感染者前面但是速度慢(因为不限时,总会有追上的时候)
//我们把会被感染的人中的最大速度和最小速度记录下来,我们最后还要判断在感染者右边而且速度也比第一个感染者快,但是如果他比会感染的人的最大速度慢的话,他还是会被感染
if ((s[i] < s[k] && v[i] > v[k]) || (s[i] > s[k] && v[i] < v[k]))
{//这里为什么不sum++呢,因为我后面一个循环就也会把这种情况判断一次
mymax = max(mymax, v[i]);
mymin = min(mymin, v[i]);
}//这里用到了max和min函数,注意要加头文件algorithm
if (s[i] == s[k])//单纯的倒霉蛋
{
sum++;
mymax = max(mymax, v[i]);
mymin = min(mymin, v[i]);
}
}
因为我们判断的最小速度一定是v[i]<v[k]里面的,最大速度一定是v[i]>v[k]里面的,所以后面的判断就不存在最小速度的感染者在左边,因此左边的人的速度只要<=mymin就一定不会被感染
第二次判断就是找出除了一开始的倒霉蛋的其他感染者
for (int i = 1; i <= n; i++)
{
//注意!!!!!!!这里的最小速度和最大速度均是已经确定的感染者的,不是所有人的
//如果在初始感染者左边速度比最小速度快,那么一定会超过最小速度的这个感染者
//同理,如果在感染者右边比最大速度慢,那么一定会被最大速度的这个感染者追上
if ((s[i] < s[k] && v[i] > mymin) || (s[i] > s[k] && v[i] < mymax))
{
sum++;
}
}
最后就上完整的代码吧
#include<iostream>
#include <algorithm>
using namespace std;
int mymax = 0, mymin = 1000;
int main()
{
int n, k;
cin >> n >> k;
int* s = new int[n+1];
for (int i = 1; i < n + 1; i++)
{
cin >> s[i];
}
int* v = new int[n+1];
for (int j = 1; j < n + 1; j++)
{
cin >> v[j];
}
int sum = 0;
for (int i = 1; i <= n; i++)
{
//被感染
if ((s[i] < s[k] && v[i] > v[k]) || (s[i] > s[k] && v[i] < v[k]))
{
mymax = max(mymax, v[i]);
mymin = min(mymin, v[i]);
}
if (s[i] == s[k])
{
sum++;
mymax = max(mymax, v[i]);
mymin = min(mymin, v[i]);
}
}
for (int i = 1; i <= n; i++)
{
if ((s[i] < s[k] && v[i] > mymin) || (s[i] > s[k] && v[i] < mymax))
{
sum++;
}
}
cout << sum;
delete[]s;
delete[]v;
return 0;
}