问题描述
长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。
每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。
当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。
这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。
当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。
这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
输入格式
第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。
接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数据代表的蚂蚁感冒了。
接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数据代表的蚂蚁感冒了。
输出格式
要求输出1个整数,表示最后感冒蚂蚁的数目。
样例输入
3
5 -2 8
5 -2 8
样例输出
1
样例输入
5
-10 8 -20 12 25
-10 8 -20 12 25
样例输出
3
思路:
我们可以从第一只那只感冒的蚂蚁入手,实际上,如果第一只蚂蚁向右爬,则它出发的位置右边的蚂蚁中向左爬且离第一只蚂蚁最近的那只会被传染,然后双方会掉头爬行,接下来,第一只蚂蚁左边的蚂蚁中向右爬行且离第一只蚂蚁最近的那只会被传染,双方再掉头。而对于一开始第一只被传染的那只蚂蚁来说,它会传染给他右边向左爬且最近的蚂蚁……
所以,将问题简化,实际上就是向右爬的第一只感冒蚂蚁会先传染它右边所有向左爬的蚂蚁,掉头向左爬时会传染给左边所有向右爬的蚂蚁。
同理,若第一只蚂蚁开始时是向左爬,被传染的蚂蚁=左边所有向右爬的蚂蚁+右边所有向左爬的蚂蚁。
注意这种思想需要有个第一只感冒的蚂蚁是否会掉头的判断,因为第一只蚂蚁向左(或右)爬的时候,若不会遇到一只迎面而来的蚂蚁使它掉头的话,则即使右边有向左爬的蚂蚁,也不会被其传染。
(两只蚂蚁碰撞可以看做不碰撞,擦肩而过)
#include<stdio.h>
#include<string.h>
struct Node{
int pos,dir;
};
struct Node nodes[55];
int n;
int main()
{
scanf("%d",&n);
for(int i = 0; i < n; ++i){
scanf("%d",&nodes[i].pos);
if(nodes[i].pos > 0){
nodes[i].dir = 1;
}
else{
nodes[i].pos *= -1;
nodes[i].dir = -1;
}
}
int turn = 0;//记录是否会让第一只蚂蚁转头
int ans = 1 ;
if(nodes[0].dir == 1){//开始头向右的情况
for(int i = 1; i < n; ++i){
if(nodes[i].pos > nodes[0].pos && nodes[i].dir == -1){
turn = 1;
++ans;
}
}
if(turn)
for(int i = 1; i < n; ++i){
if(nodes[i].pos < nodes[0].pos && nodes[i].dir == 1){
++ans;
}
}
}
else{//开始头向左的情况
for(int i = 1; i < n; ++i){
if(nodes[i].pos < nodes[0].pos && nodes[i].dir == 1){
turn = 1;
++ans;
}
}
if(turn) //只有转头才可以让另一半蚂蚁感冒
for(int i = 1; i < n; ++i){
if(nodes[i].pos > nodes[0].pos && nodes[i].dir == -1)
++ans;
}
}
printf("%d\n",ans);
return 0;
}