蓝桥杯——【第五届】蚂蚁感冒【B组】

长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。

  每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。

  当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。

  这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。

  请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。


输入格式

第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。

接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数据代表的蚂蚁感冒了。

输出格式

输出1个整数,表示最后感冒蚂蚁的数目。

数据范围

1<n<501<n<50,

0<|Xi|<1000<|Xi|<100


输入样例1:

3

5 -2 8

输出样例1:

1

输入样例2:

5

-10 8 -20 12 25

输出样例2:

3

原题链接

问题1:如何解决蚂蚁碰面后转向的问题?

问题2:哪些蚂蚁会被感染?哪些不会?

举例说明:

如图:①情况:

右边:D 会被感染,而C、E不会被感染,而D被感染之后掉头,红色蚂蚁此时向左走,追不上C、E,因此右边被感染只有D

左边:由于B是朝着红色蚂蚁来的,那么B也会被感染,而A不会被感染。

但是,如果 右边没有方向朝左的蚂蚁,那么感染的蚂蚁数就是1(本身)

综上所述:红色蚂蚁的右边,方向是朝左的蚂蚁会被感染(前提)。左边方向朝右的蚂蚁也会被感染

②情况:

左边:B会被感染

右边:红色蚂蚁掉头之后,D会被感染

但是,如果 左边没有方向朝右的蚂蚁,那么感染的蚂蚁数就是1(本身)

综上所述:红色蚂蚁的左边,方向朝右的蚂蚁会被感染(前提)。右边方向朝左的蚂蚁也会被感染。

综上,无论红色蚂蚁是朝左还是朝右,我们只用统计左边方向朝右的 和 右边方向朝左 的蚂蚁数量即可。

_______________________________________________________________________________________________________

代码思路:

题目条件: Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左

数据的符号只代表方向,因此,我们可以只以数值来区分蚂蚁的相对位置,假设A蚂蚁是-5,B蚂蚁是-3,则绝对值 B蚂蚁 < A蚂蚁,那么B蚂蚁就在A蚂蚁的左边,并且是向左走的,A蚂蚁也是向左走的。

1.当首只蚂蚁右行:

所有右边左行的蚂蚁全部感冒;并且该蚂蚁左边右行的所有蚂蚁全部感冒(该感冒蚂蚁的右边有左行的蚂蚁,这个“并且”结论才成立,如果该感冒蚂蚁右边没有左行的蚂蚁,那么其左边右行的蚂蚁也不会被感染)

2.当首只蚂蚁左行

所有左边右行的蚂蚁全部感冒;并且该蚂蚁右边左行的所有蚂蚁全部感冒(该感冒蚂蚁的左边有右行的蚂蚁,这个“并且”结论才成立,如果该感冒蚂蚁左边没有右行的蚂蚁,那么其右边左行的蚂蚁也不会被感染)

(因为是同等的速度,所以,不会存在后面的蚂蚁追上前面的,而这个竿子长度也是无用条件,不需要去考虑)

#include<iostream>
#include<algorithm> // 导入algorithm头文件,用于abs()函数
using namespace std;

const int N = 55; // 定义常量N为55,表示最多有55只蚂蚁

int a[N]; // 定义长度为N的数组a,用于存储蚂蚁的位置信息

int main()
{
    int n; // n表示蚂蚁的数量
    cin >> n; // 输入蚂蚁的数量

    for (int i = 0; i < n; i++)
    {
        cin >> a[i]; // 循环读入蚂蚁的位置信息
    }

    int left_r = 0, right_l = 0; // 定义left_r和right_l,分别用于记录在感染蚂蚁的左侧和右侧的、与感染蚂蚁方向相反的蚂蚁数量

    for (int i = 1; i < n; i++) // 从第二只蚂蚁开始遍历数组a
    {
        if (abs(a[i]) < abs(a[0]) && a[i] > 0)
        {
            left_r++; // 如果该蚂蚁在感染蚂蚁的左侧,且方向为向右,则left_r加1
        }
        else if (abs(a[i]) > abs(a[0]) && a[i] < 0)
        {
            right_l++; // 如果该蚂蚁在感染蚂蚁的右侧,且方向为向左,则right_l加1
        }
    }

    // 如果感冒蚂蚁是向右走,那么必须右边有向左走的才能感染
    // 如果感冒蚂蚁是向左走,那么必须左边有向右走的才能感染
    // 也就是说必须有与感冒蚂蚁反向,否则感染不了 
    if (a[0] > 0 && right_l == 0 || a[0] < 0 && left_r == 0)
    {
        cout << 0; // 输出0,表示无法感染其他蚂蚁
    }
    else
    {
        cout << left_r + right_l + 1 << endl; // 输出能够感染的蚂蚁数量,即left_r + right_l + 1
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_29992017/article/details/129650214