一個靠巧妙得出答案的題目:
歷屆試題 螞蟻感冒
問題描述
長100厘米的細長直桿子上有n只螞蟻册招。它們的頭有的朝左岔激,有的朝右。
每只螞蟻都只能沿著桿子向前爬是掰,速度是1厘米/秒虑鼎。
當(dāng)兩只螞蟻碰面時,它們會同時掉頭往相反的方向爬行键痛。
這些螞蟻中炫彩,有1只螞蟻感冒了。并且在和其它螞蟻碰面時絮短,會把感冒傳染給碰到的螞蟻江兢。
請你計算,當(dāng)所有螞蟻都爬離桿子時丁频,有多少只螞蟻患上了感冒杉允。
輸入格式
第一行輸入一個整數(shù)n (1 < n < 50), 表示螞蟻的總數(shù)邑贴。
接著的一行是n個用空格分開的整數(shù) Xi (-100 < Xi < 100), Xi的絕對值,表示螞蟻離開桿子左邊端點的距離叔磷。正值表示頭朝右拢驾,負值表示頭朝左,數(shù)據(jù)中不會出現(xiàn)0值改基,也不會出現(xiàn)兩只螞蟻占用同一位置繁疤。其中,第一個數(shù)據(jù)代表的螞蟻感冒了秕狰。
輸出格式
要求輸出1個整數(shù)稠腊,表示最后感冒螞蟻的數(shù)目。
樣例輸入
3
5 -2 8
樣例輸出
1
樣例輸入
5
-10 8 -20 12 25
樣例輸出
3
剛接觸題目時有點沒有思路鸣哀,因為會想的太多架忌,在思考每一個螞蟻的行動狀態(tài)甚至每個時候的螞蟻狀態(tài)是一件勞而無功的事情,以至于走了彎路诺舔。知道查看了題解鳖昌,才意識到了解題的要路。
要清楚的幾點是:
1低飒,每個螞蟻的速度是相同的许昨,一個螞蟻如果和感冒螞蟻在同一方向上前進,除了螞蟻回頭褥赊,是不會相遇的糕档。
2,螞蟻的轉(zhuǎn)頭可以看做是兩個螞蟻一個向左一個向右拌喉,碰見后反轉(zhuǎn)速那,一個向右一個向左,而題目所求的是感冒的螞蟻數(shù)目尿背,所以感染的螞蟻個體對結(jié)果并不會產(chǎn)生影響端仰。
3,在感冒的螞蟻傳染給正常螞蟻并反轉(zhuǎn)后田藐,正常螞蟻代替原螞蟻繼續(xù)向原來的方向傳染荔烧,在相反的方向,也開始傳染感冒汽久。
總結(jié):
如果原來的螞蟻行動方向是向左鹤竭,
那么該螞蟻左方的向右行動的螞蟻會被傳染。
該螞蟻右方的向左行動的螞蟻:
如果原來的螞蟻向后反轉(zhuǎn)景醇,那么將會被傳染臀稚。(這時左方有向右行動的螞蟻已經(jīng)被傳染)
如果左方?jīng)]有向右行動的螞蟻,那么該螞蟻不會反轉(zhuǎn)三痰,不會被傳染吧寺。
其余方向行走的螞蟻則不會被傳染窜管。
如果原始方向是向右,同理推斷稚机。
解題代碼為:
#include<iostream>
#include<cmath>
using namespace std;
#define MAX 50
int ant[MAX];
int main()
{
int i;
int n; cin>>n;
int left=0,right=0;
for (i=0;i<n;i++){
cin>>ant[i];
}
int h=abs(ant[0]);
for ( i=1;i<n;i++)
{
if (ant[i]>0&&abs(ant[i])<h)//方向向右微峰,即向右行走&&距離左端小于原螞蟻,即在其左側(cè)
left++;
else if (ant[i]<0&&abs(ant[i])>h) //方向向左抒钱,即向左行走&&距離左端大于原螞蟻,即在其右側(cè)
right++;
}
if ((left==0&&ant[0]>0)||(right==0&&ant[0]<0)) //向左行走時左側(cè)沒有向右行走的||向右行走時右側(cè)沒有向左行走的
cout<<1<<endl;
else cout<<left+right+1<<endl; //有傳染過別的螞蟻颜凯,存在反轉(zhuǎn)谋币,反方向螞蟻會被傳染。
return 0;
}