2014年第五届蓝桥杯 - 省赛 - C/C++大学A组 - G. 蚂蚁感冒

标题:蚂蚁感冒

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

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

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

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

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

【数据格式】

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

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

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

例如,输入:
3
5 -2 8
程序应输出:
1

再例如,输入:
5
-10 8 -20 12 25
程序应输出:
3

资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

Ideas

这道题一开始做的时候挺懵的,还想着用一个数组,然后不断交换元素来模拟蚂蚁爬杆的过程,但是发现太复杂了。

其实比较难操作是“当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。”

其实可以看成穿越!

也就是说,虽然实际上它们是掉头爬行了,但是我们模拟的时候其实可以看作是一只蚂蚁穿过了另一只蚂蚁。

如果能这么想的话,其实问题就很简单了,我们只需要找到感冒的蚂蚁,在它前进的方向上,所有与它对着头爬的蚂蚁都会被感染,而在它爬行的相反方向,也就是它的背后,如果感冒蚂蚁前方有被感染的蚂蚁,所有跟它后面同一个方向爬的蚂蚁都会被它往前爬的过程中感染的蚂蚁感染。

当感冒蚂蚁往右爬时,所有在它前面的,即位置大于感冒蚂蚁位置的,只要往左爬,即小于0,则会被感染,所有在它后面的,即位置小于感冒蚂蚁位置的,只要往右爬,即大于0,则会被感染。

当感冒蚂蚁往左爬时,所有在它前面的,即位置小于感冒蚂蚁位置的,只要往右爬,即大于0,则会被感染,所有在它后面的,即位置大于感冒蚂蚁位置的,只要往左爬,即小于0,则会被感染。

可以发现,只要其它蚂蚁的位置绝对值大于感冒蚂蚁,且小于0,即会被感染,只要其它蚂蚁的位置绝对值小于感冒蚂蚁,且大于0,即会被感染。

OK,开始写代码。

Code

C++

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n; 
int main()
{
    scanf("%d", &n);
    int pivot, left = 0, right = 0;
    scanf("%d", &pivot);

    for (int i = 1; i < n; i++)
    {
        int x;
        scanf("%d", &x);
        //找到感冒蚂蚁左边边且向右走的
        if (abs(x) < abs(pivot) && x > 0) right++;
        //找到感冒蚂蚁右边且向左走的
        if (abs(x) > abs(pivot) && x < 0) left++;
    }
    //特殊情况
    if ((pivot < 0 && right == 0) || pivot > 0 && left == 0) puts("1");
    else printf("%d\n", left + right + 1);

    return 0;
}

C++代码来源于AcWing
作者:Chengte
链接:https://www.acwing.com/solution/content/7077/

Python

if __name__ == '__main__':
	n = int(input())
	left, right = 0, 0
	nums = list(map(int, input().split()))
	for val in nums:
		if abs(val) > abs(nums[0]) and val < 0:
			right += 1
		if abs(val) < abs(nums[0]) and val > 0:
			left += 1
	if (nums[0] > 0 and right == 0) or (nums[0] < 0 and left == 0):
		print(1)
	else:
		print(left + right + 1)

在线评测:https://www.acwing.com/problem/content/description/1213/

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大风车滴呀滴溜溜地转

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值