題目描述
Leslie非常喜歡真心話大冒險的游戲。這一次游戲的規則有些不同。每個人都有自己的真心話,一開始每個人也都只知道自己的真心話。每一輪每個人都告訴指定的一個人他所知道的所有真心話,那么Leslie想知道,多少輪后他能知道所有人的真心話呢?題目保證數據有解。
輸入
第一行一個數n,表示一共有n個人,編號為1~n, Leslie為第n個人。n<=1000
第二行有n個數,第i個數表示第i個人要傳遞真心話的對象。
輸出
輸出一個數x,表示第x輪后Leslie知道了所有的真心話。
輸入樣例
4
2 4 2 1
輸出樣例
2
題目鏈接:https://buaacoding.cn/problem/1971/index
寫在前面:
相信有C語言基礎的同學都不難理解遞歸。舉個簡單的例子:從前有座山,山里有座廟,廟里有個和尚,和尚在講故事,從前有座山,山里有座廟,廟里有個和尚,和尚在講故事,從前有座山...
遞歸是我們經常用到的算法,當熟悉遞歸的做法以及題目的思路時,遞歸經常可以簡化代碼量。當然,遞歸也有他的弊端,那就是遞歸是一個不斷深入的過程,在這過程中它每次都需要開辟一塊棧空間來存儲,使得遞歸的運行效率通常較低。當然,理論上,每個遞歸算法都可以轉化為非遞歸(循環)來實現。
題目分析:在每一輪當中,每個人告訴他要告訴的人他知道的真心話(好拗口)。
注意:在這一輪結束后,大家同時知道新的真心話。因為我在看有的代碼時發現有同學用循環實現時通常會為大家知道真心話添加順序,即在同一輪中,如果一個人知道新的真心話后,他接下來也會把這個真心話告訴他要告訴的人,但這其實是不對的。
思路:所有人中需要傳遞次數的最大值就是答案!
遞歸,看程序即可。
#include<stdio.h> #define MAX 1005 #define max(a,b) (a>b?a:b) int n, pass[MAX]; // pass數組用來存儲他要告訴真心話的人 int fun(int x) { if(x == n) return 0; return 1 + fun(pass[x]); } int main() { int ans = 0; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &pass[i]); for(int i = 1; i < n; i++) ans = max(ans, fun(i)); printf("%d", ans); return 0; }