游历魔法王国(校招)

魔法王国一共有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.就小易能行动的次数来讨论,当小易的行动次数小于树的最大深度的时候,那么小易此时能访问的城市数量就等于行动次数 + 1 。
2.当小易的行动次数大于树的最大深度时,则不能从最大深度的分支一直走下去。从最坏的角度来看,如果最大深度的分支没有其他分支,只有回到根结点处找另一个分支,这样损失的行动次数过多,经过的城市数量也不能达到最大,所以在这种情况下,如果要保证经过的城市最多,最长的分支是必须走完的,那么多余的行动次数可以走其他的分支,假设行动次数为n,最长分支为maxLen,那么多余的行动次数为n-maxLen,考虑到来回的问题那么多余的行动次数能经过的城市为(n - maxLen)/2,所以经过的城市数量为maxLen + (n - maxLen)/2 + 1 。
3.(本来这个题目是不会做的,后来在网上看到很多大佬的代码(大部分都是c++,别人的博客里里好像没看到Java写的,所以找了好多),讲了很多关于这个题目的分析,说是用贪心解)

代码如下:

import java.util.*;
public class MagicCountry {

    public static void main(String[] args) {

        Scanner s = new Scanner(System.in);
        //初始化maxLen
        int maxLen = 0;
        //输入城市的个数m
        int m = s.nextInt();
        //输入可行动的次数n
        int n = s.nextInt();
        int[] parent = new int[50];
        int[] depth = new int[100];
        for(int i = 1;i < m;i++) {
            parent[i] = s.nextInt();
            depth[i] = depth[parent[i]] + 1;
            if(depth[i] > maxLen) {
                maxLen = depth[i];
            }   
        }
        //System.out.println(maxLen);
        int count = 0;
        if(maxLen > n) {
            count = n;
        }else {
            count = (n - maxLen)/2 + maxLen;
        }
        System.out.println(count + 1);
        s.close();
    }
}

猜你喜欢

转载自blog.csdn.net/ydydyd00/article/details/78253486