时间限制:1.0s 内存限制:256.0MB
长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
本来觉得这道题好难,想了半天没想出来……看了别人的分析才豁然开朗。两只蚂蚁,相撞后返回,然后他们速度一样,所以相撞之后,可以看做还是原来的蚂蚁在向原来的方向前进,与另一只蚂蚁交换了灵魂,但是肉体木有变嘛~~但糟糕的是,如果它撞到的是一只感冒的蚂蚁,那么它也感冒了,这下怎么办呢?
我们来煮一个梨子(举一个例子):假如感冒的蚂蚁A在向右爬行,那么A右边向左爬行的离A最近的蚂蚁B最先与A相撞,然后B就不幸的被传染了,假设这时AB的爬行方向还未改变,那么A右边向左爬行的蚂蚁必然感冒,B左边向右爬行的蚂蚁必然感冒,而B原本就是A右边向左爬行的蚂蚁……那么,答案来了:
只要计算出A右边向左爬行的蚂蚁,和A左边向右爬行的蚂蚁,再加上A本身,就是问题的答案。当A起初是向左爬行,算法相同(不信你试试~)。
哈哈,这下问题就简单多了吧!来看一下代码实现吧~
对了,要注意一点!如果使用sort函数时不是使用默认的排序方法,一定要记得重载compare函数啊啊啊!
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Ant{
int dir;//爬行方向
int loc;//到杆子左端的距离
};
//重载排序函数
bool comp(const Ant &a, const Ant &b)
{
if(a.loc!=b.loc)
return abs(a.loc)<abs(b.loc);
}
int main()
{
Ant ant;
vector<Ant> v;
int n,m,i;//蚂蚁总数,每个蚂蚁到左端的距离(有方向)
int left,right;//左边向右爬行的蚂蚁数,右边向左爬行的蚂蚁数
int coldAnt;//感冒的蚂蚁到左端距离的绝对值
int center;//感冒蚂蚁在距离序列中的位置
int ans;
while(cin>>n)
{
left=0;
right=0;
ans=0;
v.clear();
for(i=0;i<n;i++)
{
cin>>m;
ant.loc=abs(m);
ant.dir=m<0?-1:1;
v.push_back(ant);
}
coldAnt=v[0].loc;
sort(v.begin(),v.end(),comp);
for(i=0;i<v.size();i++)
{
if(v[i].loc==coldAnt)
{
center=i;
break;
}
}
for(i=0;i<center;i++)//计算左边向右爬行的蚂蚁数
{
if(v[i].dir==1) left++;
}
for(i=center+1;i<v.size();i++)//计算右边向左行的蚂蚁数
{
if(v[i].dir==-1) right++;
}
ans=left+right+1;
cout<<ans<<endl;
}
return 0;
}