牛客 墜落的螞蟻

2021-10-08 18:28:30 字數 3383 閱讀 1860

一根長度為1公尺的木棒上有若干只螞蟻在爬動。它們的速度為每秒一厘公尺或靜止不動,方向只有兩種,向左或者向右。如果兩隻螞蟻碰頭,則它們立即交換速度並繼續爬動。三隻螞蟻碰頭,則兩邊的螞蟻交換速度,中間的螞蟻仍然靜止。如果它們爬到了木棒的邊緣(0或100厘公尺處)則會從木棒上墜落下去。在某一時刻螞蟻的位置各不相同且均在整數厘公尺處(即1,2,3,…99厘公尺),有且只有乙隻螞蟻a速度為0,其他螞蟻均在向左或向右爬動。給出該時刻木棒上的所有螞蟻位置和初始速度,找出螞蟻a從此時刻到墜落所需要的時間。

輸入:

第一行包含乙個整數表示螞蟻的個數n(2<=n<=99),之後共有n行,每一行描述乙隻螞蟻的初始狀態。每個初始狀態由兩個整數組成,中間用空格隔開,第乙個數字表示初始位置厘公尺數p(1<=p<=99),第二個數字表示初始方向,-1表示向左,1表示向右,0表示靜止。

輸出:

螞蟻a從開始到墜落的時間。若不會墜落,輸出「cannot fall!」

本題最重要的邏輯是螞蟻的相對位置永遠不變!!這個邏輯直接推導出了本題的解法之一

首先,我們來確定怎麼判斷螞蟻不會墜落,有兩種情況————

第一種:靜止的螞蟻兩邊的螞蟻都不會碰到這只螞蟻,也就是說,左邊的往左走,右邊的往右走

第二種:螞蟻的右邊有向左走的,左邊有向右走的,按照一般的理解一開始靜止的螞蟻一定

是會掉下去的,但是注意一開始提到的那個邏輯,螞蟻的相對位置不變,並且移動方向也不變!

什麼意思呢,比如整個樹枝上向左走有n個,向右走有m個。那麼在任何時間向左走和向右走的

數量都是n和m,這時候結合螞蟻的相對位置,在無限的時刻,向左走的n只螞蟻都掉下了樹枝,

這n只不一定都是原來初始狀態向左走的,但一定是一開始左邊的n只螞蟻,因為相對位置不變。

同理,右邊m只也都掉出去了,那麼如果n==m,並且靜止的螞蟻左右都有n(m)只。那麼,在某個時刻,

左邊n只無論之前是向**走的,一定都下去了。

所以,我們把結論推廣,只要靜止的螞蟻左邊的螞蟻數量,等於所有螞蟻中往左走的數量,

亦或者右邊的等於向右走的那麼它就不會掉下去。

那麼,怎麼判斷螞蟻什麼時候下去呢

這時候肯定能確定這只螞蟻左右數量不等了。接下來就是很巧妙的思想了,如果該螞蟻

左邊的螞蟻數量小於向左走的螞蟻數量,那麼它總會加入向左走的大軍最後掉落。這時候

我們巨集觀的去看,我們定位所有在向左走的螞蟻,並且定位靜止的那只螞蟻的位置,並且

標記為k(第k個螞蟻),這時開始移動,我們看不到螞蟻之間交換速度,我們只知道他們

像是穿過對方繼續往下走。讓螞蟻繼續走,直到某一刻我們觀察到第k只向左走的螞蟻

掉下去了,暫停。現在考慮所有螞蟻的相對位置不變!如果是第k個向左走的螞蟻下去了

那麼他之前的向左走的螞蟻都下去了,反映到相對位置上來說,就是樹枝上左邊k-1只都下去了,

那麼這一瞬間掉下去的想必就是相對位置在第k的螞蟻了————也就是原來靜止的那只。

也就是說一開始所有向左走的螞蟻中,第k個螞蟻要走多遠,就是最終答案!!

同樣,如果反過來,右邊的少於向右走的,也一樣。

相關**

#include

#include

#include

using

namespace std;

struct ant};

intmain()

//現在的target就是靜止的螞蟻左邊的數量了

bool flag =

false

;int ans;

if(toleft == target)

flag =

true

;else

if(toleft > target)

//這樣的話我們要找的就是所有向左走的螞蟻中,第target螞蟻

else

if(ant[i]

.direct ==-1

) cnt++;}

}else

//向左走的螞蟻少,那麼目標螞蟻會向右落下

else

if(ant[i]

.direct ==1)

cnt++;}

}if(flag)

printf

("cannot fall!\n");

else

printf

("%d\n"

,ans);}

//while

return0;

}//main

題目看起來很複雜而且要模擬的話也比較麻煩,但是如果仔細觀察的話就會發現這樣乙個事實:兩隻非a(a螞蟻是剛開始靜止的那只螞蟻)螞蟻相碰的時候交換各自的速度其實相當於兩隻螞蟻還是各走各的路,沒有碰頭,速度不變。

然後假設螞蟻a的位置是pos

基於上面的結論

那麼在pos左邊並且初速度向左-1的螞蟻 還有 在pos右邊並且初速度向右+1的螞蟻不會對a造成任何影響

這兩種型別的螞蟻可以忽略掉

然後就剩下在pos左邊速度向右的螞蟻(設為left類螞蟻)和在pos右邊速度向左的螞蟻(設為right類螞蟻)了

還要觀察出乙個結論是 題目實質上每個螞蟻的相對位置不會變化

也就是說假設a在b左邊 那麼不可能在乙個時間a跑b的右邊去了

可以模擬一下 然後把模型轉化

這樣可以推出螞蟻a不會掉落的情況只有是在它左邊left類螞蟻個數==它右邊right類螞蟻個數

其它情況螞蟻a都會掉下去

你可以想象成螞蟻a左邊離它最近的螞蟻和右邊離它最近的螞蟻抵消掉 左邊第二近的與右邊第二近的抵消掉…

至於掉到哪邊 就看left和right類螞蟻哪個少些 哪個少它就掉哪邊

掉的時間點: left螞蟻和right螞蟻其中一類抵消完後剩下的第乙個螞蟻掉落時間就是a的掉落時間了。

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

struct anta[

1005];

intmain()

int ln=

0,rn=0;

//a螞蟻左邊向右走的螞蟻數量和在右邊向左走的螞蟻數量

for(

int i=

0;i(ln==rn)cout<<

"cannot fall!"

<

else

if(ln>rn)

else

}return0;

}

墜落的螞蟻

一根長度為1公尺的木棒上有若干只螞蟻在爬動。它們的速度為每秒一厘公尺或靜止不動,方向只有兩種,向左或者向右。如果兩隻螞蟻碰頭,則它們立即交換速度並繼續爬動。三隻螞蟻碰頭,則兩邊的螞蟻交換速度,中間的螞蟻仍然靜止。如果它們爬到了木棒的邊緣 0或100厘公尺處 則會從木棒上墜落下去。在某一時刻螞蟻的位置...

墜落的螞蟻 思維 模擬

第一行包含乙個整數表示螞蟻的個數n 2 n 99 之後共有n行,每一行描述乙隻螞蟻的初始狀態。每個初始狀態由兩個整數組成,中間用空格隔開,第乙個數字表示初始位置厘公尺數p 1 p 99 第二個數字表示初始方向,1表示向左,1表示向右,0表示靜止。輸出描述 螞蟻a從開始到墜落的時間。若不會墜落,輸出 ...

poj 1003 墜落的螞蟻

描述 一根長度為1公尺的木棒上有若干只螞蟻在爬動。它們的速度為每秒一厘公尺或靜止不動,方向只有兩種,向左或者向右。如果兩隻螞蟻碰頭,則它們立即交換速度並繼續爬動。三隻螞蟻碰頭,則兩邊的螞蟻交換速度,中間的螞蟻仍然靜止。如果它們爬到了木棒的邊緣 0或100厘公尺處 則會從木棒上墜落下去。在某一時刻螞蟻...