输入包括多组测试数据。
每组测试数据包括一个整数n(1≤n≤20)。
输入以0结束,该行不做处理。
每组测试数据对应一行输出。
包括两个整数a,b。
分别代表开始时最小需要的桃子数,和结束后老猴子最少能得到的桃子数。
5 1 0
3121 1025 1 1
从题目中来看,小猴子每次将桃子均分为 5 堆时都会多出来 1 个,所以为了方便计算,我们在最开始时就借给猴子们 4 个桃子,这样的话,每次都可以刚好均分为 5 堆。
假设在开始时就有
X
个桃子,借给猴子们4
个后,此时就一共有X+4
个桃子。
当第一只小猴子来时,它将X+4
个桃子均分为 5 堆后,拿走(X+4)*(1/5)
个,剩余(X+4)*(4/5)
个桃子。在这里,有人可能会有疑问:给老猴子的那个桃子去哪里呢?其实,小猴子拿的那一部分就包括了这一个桃子,并且小猴子也没有多得桃子,它实际上得到的桃子数为(X+4)*(1/5) - 1 = (X-1)*(1/5)
,这和在不借给它们 4 个桃子的情况下得到的数量是一样的,不过此时剩余的桃子数相较于之前多了(X+4)*(4/5) - (X-1)*(4/5) = 4
个,但这样就恰巧保证了下一只小猴子分桃时,也能刚好均分为 5 堆。由此可见,所有的小猴子都不会多得桃子,老猴子也不会少得桃子,并且每次小猴子都能刚好将桃子均分为 5 堆,而借给的那 4 个桃子每次都在剩余的那部分里,最后去除即可。
当第二只小猴子来时,它将(X+4)*(4/5)
个桃子均分为 5 堆后,拿走(X+4)*(4/5)*(1/5)
个,剩余(X+4)*(4/5)^2
个桃子。
当第三只小猴子来时,它将(X+4)*(4/5)^2
个桃子均分为 5 堆后,拿走(X+4)*(4/5)^2*(1/5)
个,剩余(X+4)*(4/5)^3
个桃子。
.....
依次类推,当第 n 只小猴子(最后一只小猴子)来时,它将(X+4)*(4/5)^(n-1)
个桃子均分为 5 堆后,拿走(X+4)*(4/5)^(n-1)*(1/5)
个,剩余(X+4)*(4/5)^n
个桃子。
为了满足题目最后的要求,也就是要保证最后剩余的桃子数最少且为整数,那么当 X+4 = 5^n
时,刚好满足要求,此时可得出:
(1)开始时的总桃子数:X = 5^n - 4
(2)老猴子最后能得到的桃子数:n + (X+4)*(4/5)^n - 4 = n + 4^n - 4
因为老猴子能得到的桃子主要有两个来源:一是每个小猴子都要给一个,有 n 只小猴子,就可以得到 n 个;二是最后剩余的桃子都归老猴子所有,从上面最后一次的结果来看,一共剩余了 (X+4)*(4/5)^n
个桃子,但是这里面包括我们最早借给它们的 4 个,实际上剩余的桃子数为 (X+4)*(4/5)^n - 4
,所以最后总共能得到的桃子数就是 n + (X+4)*(4/5)^n - 4
。
纯数学题,思路与前面人的思路不太一样,不用借桃子,直接根据题意来进行求解,设最少需要桃子X个:第一次经过题目的处理剩余桃子数目为:4/5(X-1)=(4/5)*X-(4/5);第二次剩余桃子个数为:4/5(4/5(X-1)-1)=((4/5)^2)*X-(4/5)^2-(4/5);第三次剩余桃子个数为:4/5(4/5(4/5(X-1)-1)-1)=((4/5)^3)*X-(4/5)^3-(4/5)^2-(4/5);......依次类推,经过n只猴子的类似处理,剩余桃子数为:4/5(4/5(4/5(....(4/5(X-1)...)-1)-1)-1)=((4/5)^n)*X)-(4/5)^n-(4/5)^(n-1)-...-(4/5)=((4/5)^n)*X)-4[1-(4/5)^n]=(X+4)*(4/5)^n-4因此,同前人的推导一致,最终,只需要满足x+4的值为5^n次方则可以保证最后能得到一个整数,满足题目的要求,因此,代码如下:#include<iostream>#include<cmath>using namespace std;int main(){ int n;while(cin >> n){if(n == 0)break;else{cout <<pow(5, n) - 4 <<" "<<pow(4, n) + n - 4 << endl;}}return 0;}
/** * 思路:因为每次分5堆都会多出来1个,所以我们借给猴子们4个,以致每次都可以刚好分成5堆 * 并且,每次给老猴子的桃子都不在我们借出的那4个中,这样最后减掉4就可以得到结果。 * 假设最初由x个桃子,我们借给猴子4个,则此时有x+4个, * 第一个猴子得到(x+4)/5,剩余(x+4)*(4/5)个 * 第二个猴子分完后剩余(x+4)*(4/5)^2个 * 第三个猴子分完后剩余(x+4)*(4/5)^3个 * 依次类推,最后一个猴子分完后剩余(x+4)*(4/5)^n * 要满足最后剩余的为整数,并且x最小,则当 x+4=5^n时,满足要求 * 此时,x=5^n-4; * 老猴子得到的数量为:old = (x+4)*(4/5)^n + n - 4 * = 4^n + n - 4 * 最后加n是因为不是剩余多出来的一个,而是小猴子给的,比如桃子是有6个,小猴子本身只能拿一个,我们借给4个,小猴就能拿两个,那多出来的哪一个给老猴子,和之前6个整除五余1一个道理 * 最后老猴子减4是还给我们借给它们的那4个 * */ import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); long n = 0; while(sc.hasNext()){ n = sc.nextInt(); if(n == 0) break; long a = (long)Math.pow(5, n); long b = (long)Math.pow(4, n); System.out.println((a-4)+" "+(b-4+n)); } } }
package xd.zm.nowcoder; /** * 思路:因为每次分5堆都会多出来1个,所以我们借给猴子们4个,以致每次都可以刚好分成5堆 * 并且,每次给老猴子的桃子都不在我们借出的那4个中,这样最后减掉4就可以得到结果。 * 假设最初由x个桃子,我们借给猴子4个,则此时有x+4个, * 第一个猴子得到(x+4)/5,剩余(x+4)*(4/5)个 * 第二个猴子分完后剩余(x+4)*(4/5)^2个 * 第三个猴子分完后剩余(x+4)*(4/5)^3个 * 依次类推,最后一个猴子分完后剩余(x+4)*(4/5)^n * 要满足最后剩余的为整数,并且x最小,则当 x+4=5^n时,满足要求 * 此时,x=5^n-4; * 老猴子得到的数量为:old = (x+4)*(4/5)^n + n - 4 * = 4^n + n - 4 * 最后老猴子减4是还给我们借给它们的那4个 * */ import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); long n = 0; while(sc.hasNext()){ n = sc.nextInt(); if(n == 0) break; long a = (long)Math.pow(5, n); long b = (long)Math.pow(4, n); System.out.println((a-4)+" "+(b-4+n)); } } }
// write your code here cpp #include<iostream> #include<math.h> using namespace std; int main() { long long n; while (cin >> n) { if (n == 0) break; long long start=pow(5,n)-4; long long old =n+pow(4,n)-4; cout<<start<<' '<<old<<endl; } return 0; }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int n = sc.nextInt(); if(n == 0){ break; } long a = (long)(Math.pow(5,n) - 4); long b = (long)( n + Math.pow(4,n) - 4); System.out.println(a +" " + b); } } }
#include <iostream> #include <vector> using namespace std; int main() { int n = 0; vector<long long> numv(21, 0); vector<long long> rv(21, 0); long long start = 0; for (int i = 1; i <= 20; ++i) { for (long long k = start; ; ++k) { int r = 0; int tmp = i; long long num = 20 * k + 1; while (tmp--) { num = (num - 1) / 5 * 4;//拿走一次后剩下的桃子 ++r; if (num % 5 != 1)//不能再继续分了 break; } if (tmp == 0) { cout << start << " " << k << endl; numv[i] = 20 * k + 1; rv[i] = r + num; start = k * 5; break; } } } cin >> n; while (n != 0) { cout << numv[n] << " " << rv[n] << endl; cin >> n; } return 0; }
#include <iostream> #include <algorithm> using namespace std; int main(){ int n; while(cin >> n){ if(n == 0){ continue; } long a = pow(5, n) - 4; long b = pow(4, n) + n - 4; cout << a << " " << b << endl; } return 0; }
#include<iostream> #include<vector> #include<string> #include<algorithm> #include<functional> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #include <exception> using namespace std; void seperatePeach(int n) { } int main(int argc,char** argv) { int n; while (cin >> n && n > 0) { cout << (long)pow(5, n) - 4 << " " << (long)pow(4, n) + n - 4 << endl; } return 0; }
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int n = sc.nextInt(); if(n == 0) break; System.out.println((long)(Math.pow(5, n) - 4) + " " + (long)(Math.pow(4, n) + n - 4)); } } }
#include<stdio.h> #include<math.h> int main() { unsigned long n, a, b; while(scanf("%lu", &n)){ if(n == 0) break; a = (unsigned long)pow(5, (double)n); b = (unsigned long)pow(4, (double)n); printf("%lu %lu\n", a-4, b-4+n); } return 0; }
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 while (in.hasNextInt()) { // 注意 while 处理多个 case int n=in.nextInt(); if(n==0){ break; }else{ long sum=(long)Math.pow(5.0,n)-4; long yu=(long)Math.pow(4.0,n)-4+n; System.out.print(sum+" "); System.out.println(yu); } } } }
// write your code here cpp /* *每次分5堆都会多出来1个,那么借给猴子们4个桃子,此时每次正好可以分成5堆 *(假设每次分给猴子们的桃子都不是借给他们的那4个桃子,最后-4就可以得到结果了) *假设最初有桃子x个,借给猴子们4个,总共有x+4个 *那么第一个小猴子得到(x+4)*(1/5),剩余(x+4)*(4/5)个 *那么第二个小猴子得到(x+4)*(4/5)*(1/5),剩余(x+4)*(4/5)^2个 *那么第三个小猴子得到(x+4)*(4/5)^2*(1/5),剩余(x+4)*(4/5)^3个 *以此类推,第n个猴子达到(x+4)*(4/5)^(n-1)*(1/5),剩余(x+4)*(4/5)^n个 *要满足最后剩余的桃子为整数,并且x最小,则当且仅当x+4=5^n,即x=5^n-4; *因此老猴子最后得到的桃子数为(5^n-4+4)*(4/5)^n+n-4=4^n+n-4 *(+n是因为每个小猴子都会将多出来的一个给老猴子,-4是刚开始借给小猴子的) */ #include <iostream> #include <algorithm> using namespace std; int main() { int n; while(cin>>n) { if(n==0)//0个猴子,结束此次循环,进行下一次循环输入 { continue; } long a=pow(5,n)-4; long b=pow(4,n)+n-4; cout<<a<<" "<<b<<endl; } return 0; }
import java.io.BufferedReader; import java.io.FileReader; import java.io.InputStreamReader; import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.Scanner; /** * Created by novas on 15-10-9. */ public class Main { public static double getLeft(double m,int n) { double sum=m; for(int i=1;i<n;i++) { m=(m*5+1)/4; sum=sum+m; } return sum; } public static void main(String[] args) throws Exception { double a=1,b=1,c=0; double temp=0; // Scanner scanner=new Scanner(System.in); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); int n=Integer.valueOf(br.readLine()); while(n!=0) { for(int i=0;i<n;i++) { a=(long)Math.pow(4,i); b=b*5; c=a-1; temp=temp*5+a; } DecimalFormat df=new DecimalFormat("0"); double count=(b*c+a+temp)/a-1; System.out.println(df.format(count)+" "+df.format(count-getLeft(c,n))); n=Integer.valueOf(br.readLine()); a=1; b=1; c=0; temp=0; } } }