蓝桥杯 历届试题 蚂蚁感冒 (思维 蚂蚁问题)

历届试题 蚂蚁感冒

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

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

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

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

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

Input

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

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

Output

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

Examples

样例输入
3
5 -2 8
样例输出
1
样例输入
5
-10 8 -20 12 25
样例输出
3




题意:

题解:

这道题很类似白书上的Ants那题, 只不过求的是所谓的感染次数, 思路其实还是比较类似的
首先, 介于蓝桥杯数据的水, 我们直接考虑模拟也是可以的, 不过这样的话N^2要求也太低了, 我们考虑一下nlogn是否可解
首先要理解, 对于两个碰撞的蚂蚁, 碰撞后反向等同于交叉穿过, 这一点要理解
对数据排序之后, 我们先找到起始感冒的蚂蚁坐标, 然后以此为界, 左边向右的和右边向左的, 是一定都会被感染的. 试想一下…
最后, 考虑特殊情况, 如果该点左边没有向右的, 那当然无法感染其他了, 反之同理


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef  long long LL;
const int inf = 1<<30;
const LL maxn = 55;

struct node{
	int x, i;
	bool d;
}a[maxn];
bool cmp(node x, node y){ return x.x < y.x;}
int main()
{
	int n, input;
	cin >> n;
	for(int i = 1; i <= n; i++){
		cin >> input;
		a[i].x = abs(input), a[i].i = i, a[i].d = (input>0)?1:0;
	}
	sort(a+1, a+1+n, cmp);
	
	int tag, left = 0, right = 0, ans = 0;
	//从左向右走的
	for(int i = 1; i <= n; i++){
		if(a[i].i==1){
			tag = i;
			break;
		}
		if(a[i].d) left++;
	}
	//从右向左走的 
	for(int i = tag+1; i <= n; i++)
		if(!a[i].d) right++;
	if(a[tag].d&&right==0 || !a[tag].d&&left==0 ) ans = 1;
	else ans = left+right+1;

	cout << ans << endl;

	return 0;
}

猜你喜欢

转载自blog.csdn.net/a1097304791/article/details/88725140