一隻神奇聰明貓走進了一間亂七八糟的房間,他不想自己動手收拾,他決定要找幫手來工作。於是他從他的帽子中變出了N隻小貓來幫他(變出來的貓,高度為原來貓的 1/(N+1) )。這些小貓也有帽子,所以每一隻小貓又從他的帽子中變出N隻小小貓來幫他。如此一直下去,直到這些小小小....貓小到不能再小(高度=1),他們的帽子無法再變出更小的貓來幫忙,而這些最小的貓只得動手打掃房間。注意:所有貓的高度都是正整數。 在這個問題中,給你一開始那隻貓的高度,以及最後動手工作的貓的數目(也就是高度為1的貓的數目)。要請你求出有多少隻貓是沒有在工作的,以及所有貓的高度的總和。 Input 每組測試資料一列,有2個正整數分別代表一開始那隻貓的高度,以及最後動手工作的貓的數目。0 0代表輸入結束。 Output 每組測試資料輸出一列,包含2個正整數分別代表有多少隻貓是沒有在工作的,以及所有貓的高度的總和。 Sample Input 216 125 
5764801 1679616 
64 1 
0 0 
Sample Output 31 671 
335923 30275911 
6 127 
以下是本人的代码: import java.util.*; 
import java.text.*; //用于格式化比较
public class Main { 
public static void main (String[] args) { 
Scanner input = new Scanner(System.in); 
NumberFormat format = new DecimalFormat(); 
format.setMaximumFractionDigits(14); 
while(true) 

int height = input.nextInt(); //第一只猫的长度
int workcats = input.nextInt(); //干活的猫
if(height==0&&workcats==0) //判断结束
break; 
int p2=0; 
long a=0; for(int n=1 ; n <Integer.MAX_VALUE ; n++) 
{ //搜索求n
String a1=format.format(((Math.log(n+1)/Math.log(n)))); 
String a2=format.format(((Math.log(height)/Math.log(workcats)))); 
if(a1.equals(a2)) 

p2=n; 
break; 
} } 
a=Math.round(Math.log(height)/Math.log(p2+1)); //求n的a次等于干活的猫
int noworkcats=0; //不干活的猫的数量
int p1=workcats; 
int h=1; 
int sumheight=workcats; //总长度
for(int i=1;i <=a;i++) 

h=h*(p2+1); 
noworkcats=noworkcats+p1/p2; 
p1=p1/p2; 
sumheight=sumheight+h*p1; 

System.out.println(noworkcats+" "+sumheight); 

    } 

解决方案 »

  1.   

    参考二叉树的性质3,http://www.chinaitpower.com/2005September/2005-09-13/199710.html  可以得到推论(证明略): 设 N0 为 n 叉树的叶子节点个数,Nn 为 有n个孩子的节点,则N0 = (n-1)Nn + 1
    对于本例来说,是完全N叉树,因此之存在N0和Nn两种节点
    若干活的小猫有X个,则有(N0-1)/(n-1)个没有干活的猫?
      

  2.   

    高度总和:
    n = ${最後動手工作的貓的數目}根据2叉数的性质2得到推论,高度为h的n叉树,至多有n^k - 1个节点。
    根据上面推论“设 N0 为 n 叉树的叶子节点个数,Nn 为 有n个孩子的节点,则N0 = (n-1)Nn + 1 ”
    由于当前是完全n叉树,设有X个小猫干活,则有(X-1)/(n-1)个小猫呆着,则共有 (X-1)/(n-1) + X 个小猫
    则数的高度为 以n为底的,(X-1)/(n-1) + X的对数,计为 HEIGHT设有X个小猫在干活,第一只进入房间的小猫高度为height,则小猫的高度总和为X + (n+1)/n*X +...... +((n+1)/n)^(HEIGHT-1)*X + height以上说明可能因为圆整的问题,不是很准,看这个:设 height为第一只进入房间的小猫高度,则
        int total = height;
        int layerNumber = n; // 每次变出的小猫个数,初始为第一只小猫变出的小猫个数
        while(1 != (Math.round(height/(n+1)) { // 一只小猫能变出n个小猫
            total += (Math.round(height/(n+1) * layerNumber;
            layNumber *= n;
        }
        total += layNumber * n
      

  3.   


    /**
      * <p>计算小猫的总高度
      * @param height 第一个小猫的高度
      * @return 总高度
      */
    public int calcTotalHeight(int height) {
        int totalHeight = height;
        int layerNumber = n; // 每次变出的小猫个数,初始为第一只小猫变出的小猫个数
        int curHeight = Math.round(height/(n+1)); // 每次变出的小猫高度,初始化为第一只小猫变出的高度
        
        while(isNotLessThanOne(curHeight)) { // 一只小猫能变出n个小猫
            totalHeight += curHeight * layerNumber;
            curHeight = Math.round(curHeight/(n+1));
            layNumber *= n;
        }
        return totalHeight;
    }
    private static boolean isNotLessThanOne(int curHeight) {
         return !(1 > curHeight)
    }