总结规律——蚂蚁感冒

题目:

长 100厘米的细长直杆子上有 n 只蚂蚁。

它们的头有的朝左,有的朝右。

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

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

这些蚂蚁中,有 1 只蚂蚁感冒了。

并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。

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

输入格式

第一行输入一个整数 n, 表示蚂蚁的总数。

接着的一行是 n 个用空格分开的整数 XiXi 的绝对值表示蚂蚁离开杆子左边端点的距离。

正值表示头朝右,负值表示头朝左,数据中不会出现 0值,也不会出现两只蚂蚁占用同一位置。

其中,第一个数据代表的蚂蚁感冒了。

输出格式

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

数据范围

1<n<50
0<|Xi|<100

输入样例1:

3
5 -2 8

输出样例1:

1

输入样例2:

5
-10 8 -20 12 25

输出样例2:

3




读题目分析
1.一根100米细长直杆子可以抽象成[0,100]的线段;

2.|Xi|是距离杆子左端点0端点的距离(蚂蚁开始的位置),Xi的符号:正号代表头朝右,负号代表头朝左,很容易让人误解为数轴上的正负数;

3.有蚂蚁爬离杆子是指爬离两个端点,朝左爬离0端点或者朝右爬离100端点,也就是说所有蚂蚁都会爬离杆子;

4.两只蚂蚁碰面时,会同时掉头往相反的方向爬行:假设有两个蚂蚁X1=8,x2=-10(两个同向的蚂蚁不会碰面),当x1,x2都走一步即可碰头,此时x1=9,x2=-9,掉头也就是x1=-9,x2=9,然后就像对方代替自己继续走一样。
(还有一点看下面样例二分析)

 

 

分析样例
样例二
-10 8 -20 12 25

    x2      x1      x4      x3      x5      
0   8(→)   10(G←)  12(→)   20(←)   25(→)   100   x1为感冒蚂蚁
0   9(G→)9(G←)     13(→)   19(←)   26(→)   100   x2和x1碰面掉头,x2被传染
0   8(G←)  10(G→)  14(→)   18(←)   27(→)   100   
0   7(G←)  11(G→)  15(→)   17(←)   28(→)   100   
0   6(G←)  12(G→)  16(→)16(←)      29(→)   100   x4和x3碰面掉头
0   5(G←)  13(G→)  15(←)   17(→)   30(→)   100   
0   4(G←)  14(G→)14(G←)    18(→)   31(→)   100   x1和x4碰面掉头,x4被感染
0   3(G←)  13(G←)  15(G→)  19(→)   32(→)   100   
0   2(G←)  12(G←)  16(G→)  20(→)   33(→)   100   
.....

  

最后有x1,x2,x4这3只蚂蚁感冒。

另外碰面除了如果其中一只感冒另一只会感冒以外,发现由于掉头,这些蚂蚁的相对排列顺序是保持不变的,那么,应该可以从开始的位置就能预测谁会被传染;

一只蚂蚁掉头之后走的路线其实是代替和它碰面蚂蚁的路线。就拿x4被感染来看,是x1走了x2的朝右路线,x4走了x3的朝左路线的原因。(其实没有x4,被传染的就是x3)既然是因为在x1右侧且朝右爬才被感染,纠结x3还是x4就没啥意义了,而且是不求哪只被感染的。

对于样例二:x1是朝左感冒蚂蚁。1.位于x1左侧且朝右蚂蚁有一个,被传染;
2.由于步骤1,x1朝右,位于x1右侧且朝左蚂蚁有一个,也被传染。

 

 

再举个x1向右的例子
10 8 20 -12 -25

    x2      x1      x4      x3      x5
0   8(→)   10(G→)  12(←)   20(→)   25(←)   100   x1为感冒蚂蚁
0   9(→)   11(G→)11(G←)    21(→)   24(←)   100   x4和x1碰头掉头,x4被传染
0   10(G→)10(G←)   12(G→)  22(→)   23(←)   100   x1和x2碰头掉头,x2被传染
0   9(G←)  11(G→)  13(G→)  22(←)   23(→)   100   这里x3和x5没有走到同一个位置,但也肯定碰面掉头了,这样看就像直接互相穿过了(可以理解为在都走到22.5掉了头)
0   8(G←)  12(G→)  14(G→)  21(←)   24(→)   100  
0   7(G←)  13(G→)  15(G→)  20(←)   25(→)   100  
0   6(G←)  14(G→)  16(G→)  19(←)   26(→)   100  
0   5(G←)  15(G→)  17(G→)  18(←)   27(→)   100
0   4(G←)  16(G→)  17(G←)  18(G→)  28(→)   100   x4和x3碰面掉头,x3被感染
.....

 

最后有4只蚂蚁感冒。

对这个例子:x1是朝右感冒蚂蚁。1.位于x1右侧且朝左蚂蚁有两个,它们都被传染;
2.由于步骤1,x朝左,位于x1左侧且朝右蚂蚁有一个,被传染。

 

总结以上两个例子:
1.x1朝左时(被感染的蚂蚁数n),
①左侧朝右的蚂蚁数≠0时,n=左侧朝右的蚂蚁数+右侧朝左的蚂蚁数+1
②左侧朝右的蚂蚁数=0时,n=1;

2.x1朝右时,
①右侧朝左的蚂蚁数≠0时,n=右侧朝左的蚂蚁数+左侧朝右的蚂蚁数+1
②左侧朝右的蚂蚁数=0时,n=1.
(就x1朝左来说,如果没有在x1左侧朝右蚂蚁,就不能发生掉头,与左侧朝右的蚂蚁碰面传染)


代码

#include<cstdio>
#include<algorithm>
const int N=60;
int x[N];
int n,num;
int left,right;//统计左侧朝右用left,右侧朝左用right
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&x[i]);
    //x1朝左朝右,都要先统计左侧朝右的蚂蚁数和右侧朝左的蚂蚁数
    for(int i=2;i<=n;i++){
        if(abs(x[i])<abs(x[1])&&x[i]>0)left++;
        if(abs(x[i])>abs(x[1])&&x[i]<0)right++;
    }
    //按x1朝左朝右分情况讨论
    if(x[1]<0){//如果x1朝左
        if(left==0)num=1;
        else num=left+right+1;
    }
    else{//如果x1朝右
        if(right==0)num=1;
        else num=right+left+1;
    }
    printf("%d",num);
    return 0;
}

 

 

posted on 2021-02-09 20:47  wang_dahua  阅读(396)  评论(0)    收藏  举报

导航