螞蟻爬杆問題
本文轉自http://blog.chinaunix.net/uid-20766194-id-1850409.html
這個問題來自編程之美這本書。
問題:有一根27釐米的木杆,在第3釐米,7釐米,11釐米,17釐米,23釐米這五個位置上各有一螞蟻。木杆很細,不能同時通過兩個螞蟻。開始的時候每個螞蟻的頭朝哪邊是不確定的,它們只會朝前走或者掉頭,但是不會後退。當任意兩隻螞蟻碰頭的時候,兩隻螞蟻會同時調頭向相反的方向走。假設螞蟻們每秒可以走一釐米的距離。編寫程序,求所有螞蟻都離開木杆的最短時間和最長時間‘
解法一:這也許是大多人會想到的方法(哈哈,我剛開始的時候也這樣想的)
考慮枚舉螞蟻的初始朝向,模擬每一個螞蟻的運動來解決問題。
解法二:
考慮,雖然兩隻螞蟻碰頭後都掉頭往相反的方向,但是,可以看作是是兩隻螞蟻相遇後,擦肩而過了(看到這裏的時候可能很多人就有一種恍然大悟的感覺了吧)。也就是說可以認爲螞蟻的運動獨立的,是否有碰頭並不是問題的中重點。
這樣雖然每個螞蟻的運動軌跡都與原來的不一樣了。但是所有的螞蟻離開木杆的最短的時間和最長時間是不變的。只需要分別計算每個螞蟻離開木杆的時間,即可求出所有螞蟻離開木杆的時間了。
這樣,程序只需要遍歷所有的螞蟻,把每個螞蟻走出木杆的最長時間(螞蟻朝離自己較遠的一端走去),最短時間(螞蟻朝離自己較近的一端走去)分別求出來,就算出最大值,這兩個最大值就是所有螞蟻離開木杆的最長時間和最短時間。
void get_time(
int length, //木杆的長度
int pos[], //開始時候每個螞蟻的位置
int ant_num, //螞蟻的數量
int speed, //螞蟻爬行的速度
int *max, //最長時間
int *min //最短時間
)
{
*max = 0;
*min = 0;
int current_max = 0;
int current_min = 0;
int i;
for (i = 0;i < ant_num;i++)
{
current_max = 0;
current_min = 0;
if (pos[i] < length / 2)
{
current_max = (length - pos[i]) / speed;
current_min = pos[i] / speed;
}
else
{
current_max = pos[i] / speed;
current_min = (length - pos[i]) / speed;
}
if (*max < current_max)
*max = current_max;
if (*min < current_min)
*min = current_min;
}
}
擴展問題:
1、第i個螞蟻什麼時間走出木杆。
2、螞蟻一共碰了多少此頭