蚂蚁感冒
这是一道蓝桥杯上的题先看一下题目:
1.长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。
2.每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。
3.这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
4.请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
我个人的分析(见下):
1.乍一看题目有点复杂,但是正如有人所说到的一点,两只蚂蚁相碰然后掉头,这里的掉头其实是不用管的,还是可以认为在原来的方向上继续前进。
2.然后就是我对本题的看法:
这个题我的思路就是用一个数组表示出来各个蚂蚁在数轴上的真实位置,然后确定第一只蚂蚁的运动方向,然后在这个数组中以第一只蚂蚁的位置为基准点,如果第一只蚂蚁的初始方向为向左👈,则向前遍历数组,寻找与之方向向右👉的蚂蚁,因为这些蚂蚁必被感染。然后再向后遍历与第一只蚂蚁同向👈的蚂蚁,因为这些蚂蚁也会被前面过来的蚂蚁所感染。第一只蚂蚁初始方向向右的话,则仅仅把上面的过程调转就 OK 了。😀(不畏难)
<若文字理解不了,代码见下>
#include <stdio.h>
#include <math.h>
int count=0; //表示被传染的数量
void swap(int* a,int* b)
{//仅仅用来交换位置的
int k;
k=*a;
*a=*b;
*b=k;
}
void paixu(int* a,int n,int* jihao)
{
int i,j;
int temp;
for(i=0;i<n;i++)
{
temp=i;
for(j=i;j<n;j++)
{
if(a[temp]>a[j])
temp = j;
}
if(temp!=i)
{
swap(&a[temp],&a[i]);
swap(&jihao[temp],&jihao[i]);
}
}
}
int main()
{
int i,n,ant[50],antindex[50];
int bnt[50];
int ganmao=0,firstindex;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&ant[i]);
antindex[i]=i; //为每个蚂蚁编上号
bnt[i] = abs(ant[i]);
}
ganmao = ant[0]; //记录下第一只感冒的蚂蚁的位置
paixu(bnt,n,antindex);
for(i=0;i<n;i++)
{
bnt[i]=ant[antindex[i]]; //这一步就相当于在数轴上画出来各个蚂蚁的位置,并且正负号表示方向
}
for(i=0;i<n;i++)
{
if(ganmao==bnt[i])
{
firstindex = i+1; //第一只蚂蚁在数轴上的第几个位置
break;
}
}
if(ganmao<0) //第一只蚂蚁初始方向向左<-
{
for(i=0;i<firstindex-1;i++)
{
if(bnt[i]>0)//说明第一只蚂蚁的前面有向右运动的蚂蚁,这些蚂蚁必然会被第一只蚂蚁感染
count++;
}
if(count>0)
{
for(i=firstindex;i<n;i++)
{
if(bnt[i]<0)
//这里的意思紧承上面,就是说如果向右运动的蚂蚁被感染
count++;
//在他们继续的运动中必然会跟之后向左的蚂蚁相碰面
}
}
}
else //说明第一只蚂蚁初始方向向右->
{
for(i=firstindex;i<n;i++)
{
if(bnt[i]<0)
count++;
}
if(count>0)
{
for(i=0;i<firstindex-1;i++)
{
if(bnt[i]>0)
count++;
}
}
}
//printf("最后一共患病的蚂蚁有%d只",count+1);
printf("%d",count+1);
return 0;
}
我再对上面的代码解释一下吧:
-
ant[50]是初始输入的位置 antindex[50]用来记录蚂蚁的序号,是第几只蚂蚁
-
然后取ant[]数组的绝对值,排序,这里也要跟着交换蚂蚁的序号!
-
然后就是相当于在数轴上刻画这个蚂蚁的位置 并且找到第一只蚂蚁。然后就用一个简单的选择结构去判断就行了。
如果大家有什么好的看法欢迎留言😀~