(網易2018校招筆試)[程式設計題] 遊歷魔法王國

Roninwz發表於2017-10-10

題目:

魔法王國一共有n個城市,編號為0~n-1號,n個城市之間的道路連線起來恰好構成一棵樹。
小易現在在0號城市,每次行動小易會從當前所在的城市走到與其相鄰的一個城市,小易最多能行動L次。
如果小易到達過某個城市就視為小易遊歷過這個城市了,小易現在要制定好的旅遊計劃使他能遊歷最多的城市,請你幫他計算一下他最多能遊歷過多少個城市(注意0號城市已經遊歷了,遊歷過的城市不重複計算)。 
輸入描述:
輸入包括兩行,第一行包括兩個正整數n(2 ≤ n ≤ 50)和L(1 ≤ L ≤ 100),表示城市個數和小易能行動的次數。
第二行包括n-1個整數parent[i](0 ≤ parent[i] ≤ i), 對於每個合法的i(0 ≤ i ≤ n - 2),在(i+1)號城市和parent[i]間有一條道路連線。


輸出描述:
輸出一個整數,表示小易最多能遊歷的城市數量。

輸入例子1:
5 2
0 1 2 3

輸出例子1:
3

程式碼:

  1. #include<iostream>  
  2. #include<vector>  
  3. #include<algorithm>  
  4. using namespace std;  
  5.   
  6. void traversal(int n,int L,vector<int> &parent){  
  7.     int maxlen=0;  
  8.     vector<int> dp(n);  
  9.     for(int i=0;i<n-1;i++){  
  10.         dp[i+1]=dp[parent[i]]+1;  
  11.         maxlen=max(maxlen,dp[i+1]);   //使用貪心演算法計算最長鏈的長度  
  12.     }   
  13.     int validpath=min(maxlen,L);  
  14.     cout<<min(n,1+validpath+(L-validpath)/2);      
  15. }  
  16. int main(){  
  17.     int n,L;  
  18.     cin>>n>>L;  
  19.     vector<int> parent;  
  20.     for(int i=0;i<n-1;i++){  
  21.         int temp;  
  22.         cin>>temp;  
  23.         parent.push_back(temp);  
  24.     }  
  25.     traversal(n,L,parent);  
  26.     return 0;  
  27. }  

分析:

思路就是:求出最長的那條鏈,然後與L比較,當L>maxlen時,存在回馬槍的可能
寫的時候不知道如何處理回馬槍的情況,還是參考了大佬的程式碼
  1. (L-validpath)/2  
這個式子表示先走非最長路徑,後走最長路徑。
L-validpath的值即為來回非最長路徑的總步數,除以二即為訪問過的城市數量。

validpath為最長路徑的步數。


轉載來自:http://blog.csdn.net/gcola007/article/details/77923536

相關文章