蓝桥杯 蚂蚁感冒

来源:互联网 发布:linux tomcat运行状态 编辑:程序博客网 时间:2024/04/28 03:50
问题描述
  长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


——————————————————————————————————————————————————————————————————————————————————————————————————————


刚开始想这道题时晕头转向的,满脑子都是碰到一起又掉头回去的蚂蚁,但是只要思维转换一下,把题目描述的情况等效为另一种情况,一切就会豁然开朗了。这种情况就是两只蚂蚁碰见后不会往相反方向爬行,而是直接穿透过去,朝着原方向爬行。

这样一来,我们只需要考虑两种会被传染的情况:

  1. 与最初感冒的蚂蚁相向爬行的蚂蚁会被传染,而最初感冒的蚂蚁所面向的同向爬行的蚂蚁,由于速度一样而且也不会掉头,所以不会被传染。
  2. 如果存在与最初感冒的蚂蚁相向爬行的蚂蚁,那么这只蚂蚁会被传染,则初感冒的蚂蚁身后相向爬行的蚂蚁也会因此被感染到。

根据第一只蚂蚁爬行的方向,将上面两点再分为向左和向右分别考虑。具体的算法步骤首先是将存储有每个蚂蚁位置信息的元素,按从小到大排序好,如果第一个被感染的蚂蚁是向左爬行的,则从最左边的蚂蚁开始,一直到第一个被感染的蚂蚁的位置,统计有几个是向右爬行的蚂蚁,这几只蚂蚁都会被感染。如果存在有向右爬行被感染的蚂蚁,再从第一个被感染的蚂蚁的位置到最右边的蚂蚁,统计有几只是向左爬行的蚂蚁,他们也都会被感染。如果第一个被感染的蚂蚁是向右爬行的,上述步骤则相反。


代码写起来不多,来看一下:

#include<iostream>#include<algorithm>using namespace std;struct node{int num; //记录蚂蚁位置 bool right;// 记录蚂蚁爬行的方向,true表示向右爬行,false表示向左爬行 }Nx[60];bool cmp(struct node c1,struct node c2) {if(c1.num < c2.num)//sort函数中,按从小到大排列的规则 {return true;}else{return false;}}int main(){int n,i,temp;int count = 1; bool flag = false; cin >> n;cin >> temp;   //用NX[0]存储第一个感冒的蚂蚁 if(temp>0){Nx[0].num = temp;Nx[0].right  = true;}else{Nx[0].num = -temp;Nx[0].right  = false;}for(i=1;i<n;i++){cin >> temp;if(temp>0)    {     Nx[i].num = temp;    Nx[i].right  = true;    }else{    Nx[i].num = -temp;    Nx[i].right  = false;    }}//将所有储存蚂蚁信息的元素按从小到大的顺序排列(第一个感冒的蚂蚁不参与排列,以免不方便确定哪个是第一个感冒的蚂蚁)sort(Nx+1,Nx+n,cmp); if(!Nx[0].right)//如果感冒的蚂蚁向左走 {i=1;while(Nx[0].num > Nx[i].num && i<n){if(Nx[i].right)//向左走的感冒的蚂蚁左侧向右走的蚂蚁会被感染 {count ++ ;flag = true;//标记感冒的蚂蚁的右侧向左走的蚂蚁会被感染 }i++;}if(flag){while(i<n){if(!Nx[i].right)//向左走的感冒的蚂蚁右侧向左走的蚂蚁会被感染     {    count ++ ;    }    i++;}} }else{//如果感冒的蚂蚁向右走 i=n-1;while(Nx[0].num < Nx[i].num && i>0){if(!Nx[i].right)//向右走的感冒的蚂蚁右侧向左走的蚂蚁会被感染 {count ++ ;flag = true;//标记感冒的蚂蚁的右侧向左走的蚂蚁会被感染 }i--;}if(flag){while(i>0){if(Nx[i].right)//向右走的感冒的蚂蚁左侧向右走的蚂蚁会被感染     {    count ++ ;    }    i--;}} cout << count; return 0;}

测试数据更少,才4组

Input:            

5
20 4 -3 -10 -22

Output:3


Input:

10
50 3 4 6 -8 12 -7 11 -60 -65

Output:8


Intput:

10
50 1 2 3 4 5 6 7 8 -59

Output:10


Intput:

10
-50 -10 -20 25 30 35 40 -60 -70 65

Output:7


0 0
原创粉丝点击