标题:求助各位大神指点迷津蓝桥杯蚂蚁感冒问题
只看楼主
Emmaer123
Rank: 1
等 级:新手上路
帖 子:39
专家分:0
注 册:2019-9-20
结帖率:66.67%
 问题点数:0 回复次数:11 
求助各位大神指点迷津蓝桥杯蚂蚁感冒问题
长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。
每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。
当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。
这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
输入
第一行输入一个整数n  (1  <   n  <   50),  表示蚂蚁的总数。
接着的一行是n个用空格分开的整数  Xi  (-100  <   Xi  <   100),  Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数  据代表的蚂蚁感冒了。
输出
要求输出1个整数,表示最后感冒蚂蚁的数目。
样例输入
5
-10  8  -20  12  25
样例输出
3


//思路:若满足 相邻的两个数组 第一个大于零第二个小于零 的条件  那么这两个会相撞  所以检查数组中每两个相邻元素  
#include <stdio.h>
int main()
{
    int i,n,flag,count=0;
    char a[1000]={0};char b[1000]={1}; //b[i]=0记录第i只蚂蚁没感染,由题意可知b[0]=1即第一个元素为感染蚂蚁
   
    scanf("%d",&n);
    for (i=0;i<n;i++)  { scanf("%s",&a[i]);}
   
    do
       {
            flag=0;
         for(i=0;i<n-1;i++)
          {
            if(a[i]>0&&a[i+1]<0)     
            {// 如检查到符合的情况,将这两个元素a[i]、a[i+1]分别变成各自的相反数
                a[i]=0-a[i];
                a[i+1]=0-a[i+1];
                i++;// i++是为了跳过a[i+1],从而在下一次循环检查a[i+2]和a[i+3]正负
                if(b[i+1]!=b[i])   //若相邻两只蚂蚁中有一只感染
                {
                    b[i+1]=1;b[i]=1;  //将两只都记录为感染   
                    count++;
                }
                flag=1;
            }
             }
       }
    while(flag=1);  // 每从i=0循环至i=n-1完,检查flag,当flag=0说明没有相邻的元素满足条件,不会有蚂蚁感染了,于是跳出循环
   
    printf("%d",count);
    return 0;
 }
 
跪求为啥编译不出来,不知道思路哪里错了,求路过大神指点一下我的思路错在哪里
我的思路是:若满足 相邻的两个数组元素第一个大于0第二个小于0的条件  那么这两个会相撞 ,当检测到满足条件的两个元素时,改变各自正负(因为由题意遇到会返回回头) ,并且如果其中只有一个感冒,感冒蚂蚁的个数加一,如此循环,直到检测不到满足条件的元素,说明以后不会有相撞的蚂蚁

[此贴子已经被作者于2019-10-15 21:47编辑过]

搜索更多相关主题的帖子: 条件 flag 表示 元素 相邻 表示 flag 条件 元素 相邻 
2019-10-14 23:04
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
是仅有这一只蚂蚁可以感染其它蚂蚁,还是所有感冒的蚂蚁都可以感染其它蚂蚁?
2019-10-15 10:49
Emmaer123
Rank: 1
等 级:新手上路
帖 子:39
专家分:0
注 册:2019-9-20
得分:0 
回复 2楼 rjsp
应该是只要是被感染过的蚂蚁碰到其他蚂蚁就可以感染
2019-10-15 12:56
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
那你试试
程序代码:
#include <stdio.h>
#include <stdlib.h>

unsigned foo( const int a[], unsigned n )
{
    unsigned left = 0; // 第一只病蚁左侧有几只朝向这只病蚁
    unsigned right = 0; // 第一只病蚁右侧有几只朝向这只病蚁
    for( unsigned i=0; i!=n; ++i )
    {
        left += ( abs(a[i])<abs(a[0]) && a[i]>0 );
        right += ( abs(a[i])>abs(a[0]) && a[i]<0 );
    }

    if( a[0]<0&&left==0 || a[0]>0&&right==0 ) // 第一只病蚁从未改向过
        return 1;
    return 1 + left + right;
}

int main( void )
{
    int a[50];
    unsigned n;
    scanf( "%u", &n );
    for( unsigned i=0; i!=n; ++i )
        scanf( "%d", &a[i] );

    printf( "%u\n", foo(a,n) );
}

2019-10-15 13:16
Emmaer123
Rank: 1
等 级:新手上路
帖 子:39
专家分:0
注 册:2019-9-20
得分:0 
回复 4楼 rjsp
我试了一下,结果正确,但我还是不明白我的思路错在哪里了
2019-10-15 16:46
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
回复 5楼 Emmaer123
首先,一开始的 scanf("%s",&a[i]); 我就看不懂
2019-10-15 16:58
自学的数学
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:46
帖 子:967
专家分:4146
注 册:2017-11-15
得分:0 
程序代码:
#include <cstdio>
#include <algorithm>

 
using namespace std;
struct Node
{
    int x;
    int dis;
    int num;
};
Node a[100];
int comp(Node a1,Node a2)
{
    if(a1.x!=a2.x)
        return a1.x<a2.x;
}
int main()
{
    int n,x;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            a[i].dis=x<0?-1:1;
            a[i].x=abs(x);
            a[i].num=i+1;
        }
        sort(a,a+n,comp);  //排序
        int tmp=0,left=0,right=0,ans=0;
        for(int i=0;i<n;i++)  //左边向右走的
        {
            if(a[i].num==1)
            {
                tmp=i;break;
            }
            if(a[i].dis==1)
                left++;
        }
        for(int i=tmp+1;i<n;i++) //右边向左走的
        {
            if(a[i].dis==-1)
                right++;
        }
        if(a[tmp].dis==1 && right==0 || a[tmp].dis==-1 && left==0)
            ans=1;
        else
            ans=left+right+1;
        printf("%d\n",ans);
    }
    return 0;
}
2019-10-15 19:40
Emmaer123
Rank: 1
等 级:新手上路
帖 子:39
专家分:0
注 册:2019-9-20
得分:0 
回复 7楼 自学的数学
请大佬能不能指点下我的思路错在哪里呢?我想了很长时间,就是想不明白,太痛苦了。
我的思路是:若满足 相邻的两个数组元素第一个大于0第二个小于0的条件  那么这两个会相撞 ,当检测到满足条件的两个元素时,改变各自正负(因为由题意遇到会返回回头) ,并且如果其中只有一个感冒,感冒蚂蚁的个数加一,如此循环,直到检测不到满足条件的元素,说明以后不会有相撞的蚂蚁,可是我把我的程序运行以后结果是错的,真的百思不得其解

[此贴子已经被作者于2019-10-15 21:57编辑过]

2019-10-15 21:49
自学的数学
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:46
帖 子:967
专家分:4146
注 册:2017-11-15
得分:0 
首先明白两只蚂蚁碰撞之后掉头和穿行过去是一样的,可以把穿行看做碰撞后掉头了,然后两个蚂蚁交换了,而是哪一只蚂蚁对结果不影响。

那么,假如第一只感冒蚂蚁向右走,那么碰到所有想左走的都会被感染,而感染后的蚂蚁必定是向左走的,那么他会把左边向右走的都感染了。

向左走的也是这样。

所以 ans = 左边向右走的  + 右边向左走的 + 1(本身)。

当然还有特殊情况,第一只感染的向右走,右边的都在向右走,那么速度一样的话它不会感染其他所有,所以 ans = 1,相反也是。
2019-10-15 22:07
Emmaer123
Rank: 1
等 级:新手上路
帖 子:39
专家分:0
注 册:2019-9-20
得分:0 
回复 9楼 自学的数学
其实我看过这个解法,也明白这个解法,这题有很多种思路,这次发帖主要是想弄明白自己的思路错在哪里,谢谢您花时间这么长的解释,但我现在还是非常困惑
2019-10-15 22:14



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-497278-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.575030 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved