遞歸 蟲子與杆

1、有一根27釐米的細木杆,在第3釐米、7釐米、11釐米、17釐米、23釐米這五個位置上各有一隻螞蟻。

木杆很細,只能同時通過一隻螞蟻。 開始時,螞蟻的頭朝左還是朝右是任意的,它們只會朝前走或調頭,但不會後退。

 當任意兩隻螞蟻碰頭時,兩隻螞蟻會同時調頭朝反方向走。

假設螞蟻們每秒鐘可以走1釐米的距離。 編寫程序,求所有螞蟻都離開木杆的最小時間和最大時間。

因爲螞蟻的朝向是任意的,對每一個螞蟻要分兩種情況考慮,而且螞蟻都在走,所以看着很複雜。

思想是交換角色,每個螞蟻碰頭之後,互換角色,不改變方向,繼續向前走。

從中間開始分,左邊的往左走,右邊的往右走,這樣就不會出現碰頭的情況,最靠近中間的那個,就是最後離開,也是代表了所有螞蟻的最短離開時間。

從中間開始分,左邊的往右走,右邊的往左走,這樣就會出現碰頭。

#include <iostream>
#include <cmath>
using namespace std;
int len = 27;
int loc[] = {3, 7, 11, 17, 23};
//m表示數組的長度
//n表示所處的數組位置
//第一個離開,最後一個離開的時間 
void f1(int m, int n, int &max, int &min){
	if(m == n){
		return;
	}
	if(loc[n] < len / 2){
		min = loc[n] < min ? loc[n] : min;
		max = (len - loc[n]) > max ? (len - loc[n]) : max;
	}
	else{
		min = (len - loc[n]) < min ? loc[n] : min;
		max = loc[n] > max ? loc[n] : max;
	}
	f1(m, ++n, max, min);
}
//m, n同上
// 所有螞蟻離開的最長和最短時間 
void f2(int m, int n, int &max, int &min){
	if(m == n){
		return;
	}
	if(loc[n] < len / 2){
		max = max = (len - loc[n]) > max ? (len - loc[n]) : max;
	}
	else{
		max = loc[n] > max ? loc[n] : max;
	}
	min = abs(len / 2 - loc[n]) < abs(len / 2 - min) ? loc[n] : min;
	f2(m, ++n, max, min);
}
int main(){
	int max = 0;
	int min = 27;
	f1(5, 0, max, min);
	cout << "max:" << max << " min:" << min << endl;
	f2(5, 0, max, min);
	cout << "max:" << max << " min:" << min << endl; 
}


2、長100釐米的細長直杆子上有n只螞蟻。它們的頭有的朝左,有的朝右。 

每隻螞蟻都只能沿着杆子向前爬,速度是1釐米/秒。

當兩隻螞蟻碰面時,它們會同時掉頭往相反的方向爬行。

這些螞蟻中,有1只螞蟻感冒了。並且在和其它螞蟻碰面時,會把感冒傳染給碰到的螞蟻。

請你計算,當所有螞蟻都爬離杆子時,有多少隻螞蟻患上了感冒。

【數據格式】

第一行輸入一個整數n (1 < n < 50), 表示螞蟻的總數。

接着的一行是n個用空格分開的整數 Xi (-100 < Xi < 100), Xi的絕對值,表示螞蟻離開杆子左邊端點的距離。

正值表示頭朝右,負值表示頭朝左,數據中不會出現0值,也不會出現兩隻螞蟻佔用同一位置。

其中,第一個數據代表的螞蟻感冒了。

要求輸出1個整數,表示最後感冒螞蟻的數目。

例如,輸入:
3 5 -2 8

程序應輸出:
1
 再例如,輸入:
 5 -10 8 -20 12 25
 程序應輸出:
3


思想還是交換角色,以上圖爲例,4往右走(因爲旗子向左飄),5和6會感染,同樣1,3也會因爲5,6感染。

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int loc[50];
//m 表示數組長度
//n 表示正在處理的元素 
//t 表示遞歸的次數 從0開始變化 遞歸兩次就可以了 
//s 表示第一個感冒的螞蟻 
void f(int m, int n, int s, int t, int &total){
    if(t >= 2){
        return ;
    }
    if(loc[n] > 0){
        for(int i = s + 1; i < m; i++){ 
            if( loc[i] < 0){
                total++;
                t++;
                f(m, i, s, t, total);
            }
        }    
    }
    if(loc[n] < 0){   
        for(int i = 0; i < s; i++){
            if(loc[i] > 0){
                total++;
                t++;
                f(m, i, s, t, total);
            }
        }
    }
}
int cmp(int a, int b){
    if(abs(a) < abs(b)){
        return 1;
    }
    return 0;
}
int find(int m, int len){
    for(int i = 0; i < len; i++){
        if(loc[i] == m){
            return i;
        }
    }
    return -1;
}
int main(){
    int m;         //螞蟻數目 
    int total = 1; //總的感冒螞蟻,一開始就會有一個感冒螞蟻 
    cin >> m;
    for(int i = 0; i < m; i++){
        cin >> loc[i];
    }
    int mid = loc[0];
    sort(loc, loc + m, cmp);
    for(int i = 0; i < m; i++){
        cout << loc[i] << " ";
    }
    mid = find(mid, m);
    cout<< endl 
        << "mid:" 
        << mid 
        << endl;
    f(m, mid, mid, 0, total); 
    cout << total;
}

發佈了17 篇原創文章 · 獲贊 3 · 訪問量 9259
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章