一隻神奇聰明貓走進了一間亂七八糟的房間,他不想自己動手收拾,他決定要找幫手來工作。於是他從他的帽子中變出了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);
}
}
}
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);
}
}
}
对于本例来说,是完全N叉树,因此之存在N0和Nn两种节点
若干活的小猫有X个,则有(N0-1)/(n-1)个没有干活的猫?
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
/**
* <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)
}