创新工厂面试题详解:共打了多少鱼

来源:互联网 发布:三菱plc触摸屏编程视频 编辑:程序博客网 时间:2024/06/10 04:31
 

最近看到一个创新工厂的面试题,很有意思,下面给出算法实现(Java代码)。如果哪位有更好的算法,请跟贴。

abcde五人打渔,打完睡觉,a先醒来,扔掉1条鱼,把剩下的分成5分,拿一份走了;b再醒来,也扔掉1条,把剩下的分成5份,拿一份走了;然后cde都按上面的方法取鱼。问他们一共打了多少条鱼,写程序和算法


共打了多少条鱼的结果有很多。但求最少打的鱼的结果是3121条鱼(应该找这5个人问问,用什么工具打了这么多条鱼)

大家可以先用计算器验证一下3121是否正确。

a开始拿鱼: (3121 - 1) / 5 = 625

同理,bcde分别获得的鱼数(不包括其扔掉的鱼)b:499 c:399 d:319 e:255

这道题最简单的方法就是枚举。从最小值开始,先看看代码(Java实现)。

 

public class Test{public static void main(String[] args){// 分别保存a至e获取的鱼数(为了方便,包括其扔掉的鱼)int[] everybody_fish = new int[5];// 临时数组,保存当前鱼数减1后除5的余数,只有都为0,才满足条件int[] temp = new int[5];// 从1扫描到10000for (int x = 1; x <= 10000; x++){// 当前已被取走多少鱼(包括被扔的鱼)int sum = 0;int i = 0;// 计算abcde各获取的鱼数for (i = 0; i < everybody_fish.length; i++){temp[i] = (x - 1 - sum) % everybody_fish.length;// 只要有一个人不能平均分配剩余的鱼,就不满足条件if (temp[i] != 0)break;everybody_fish[i] = (x - 1 - sum) / everybody_fish.length + 1;sum += everybody_fish[i];}// for循环正党结束,满足条件,输出相应的值。if (i == everybody_fish.length){System.out.print("共钓了" + x + "条鱼 ");for (i = 0; i < everybody_fish.length; i++){System.out.print((char) ('a' + i) + ":"+ (everybody_fish[i] - 1) + " ");}System.out.print("最后剩余" + (x - sum) + "条鱼 ");System.out.println("扔了" + everybody_fish.length + "条鱼");}}}}



 

运行上面的代码,会输出如下三行信息

共钓了3121条鱼 a:624 b:499 c:399 d:319 e:255 最后剩余1020条鱼 扔了5条鱼

共钓了6246条鱼 a:1249 b:999 c:799 d:639 e:511 最后剩余2044条鱼 扔了5条鱼

共钓了9371条鱼 a:1874 b:1499 c:1199 d:959 e:767 最后剩余3068条鱼 扔了5条鱼

在10000以内只有三个数满足这个条件。上面的代码是通用的,如将两个数组的长度改为6,将10000改成50000,会输出如下信息。

共钓了46651条鱼 a:7775 b:6479 c:5399 d:4499 e:3749 f:3124 最后剩余15620条鱼 扔了6条鱼

也就是说一共6个人。每个人也是先扔一条鱼,然后再将剩余的鱼6等分,取走一份。 在50000以内只有46651满足这个条件。



在本题中只有如下的代码是核心算法,其他的都是枚举和输出结果的代码。

for (i = 0; i < everybody_fish.length; i++)

{

temp[i] = (x -1 - sum) % everybody_fish.length;

// 只要有一个人不能平均分配剩余的鱼,就不满足条件

if (temp[i] !=0)

break;

everybody_fish[i] = (x - 1 - sum) / everybody_fish.length + 1;

sum +=everybody_fish[i];

}

 

下面的是跟帖回复的内容

 

Ruby 如下:
1000.upto(50000) do |sum|
times=0
temp=sum
5.times do
break if((temp-1)%5!=0)
temp = temp -(temp-1)/5 - 1
times += 1
if times==5
puts "The total number of fish is: "+sum.to_s
end
end
times=0
end
结果:
The total number of fish is: 3121
The total number of fish is: 6246
The total number of fish is: 9371
The total number of fish is: 12496
The total number of fish is: 15621
The total number of fish is: 18746
The total number of fish is: 21871
The total number of fish is: 24996
The total number of fish is: 28121
The total number of fish is: 31246
The total number of fish is: 34371
The total number of fish is: 37496
The total number of fish is: 40621
The total number of fish is: 43746
The total number of fish is: 46871
The total number of fish is: 49996

----------------------------------------------------------------------------------------------------

 

int x=1;
boolean flag = true;
for (; x < 10000; x++) {
float fashGet;
float sum = 0;
for (int i = 0; i < 5; i++) {
fashGet = (x - sum - 1) / 5;
sum += fashGet + 1;

if (fashGet % 2 == 0 || (fashGet + 1) % 2 == 0) {
flag = true;
} else {

flag = false;
break;
}
}
if (flag == true) {
System.out.println("捕到的鱼数是" + x);
break;
}
}

 

------------------------------------------------------------------------------------------

 

  1. #include "stdio.h"
  2. #include <math.h>
  3. #include <ctype.h>
  4. /* 核心算法 */
  5. int Fish_amount_speed(int p_num)
  6. {
  7. int n = p_num ;
  8. int i_up = 0;
  9. int i_up_1 = pow(5.0,n);
  10. int i_up_2 = pow(4,(n+1));
  11. int i_down = pow(4.0,n);
  12. for (int i = 1;1;i++)//i 已经是p0值,所以要计算的 人数里面 共有 p_num -1个,正好是结果需要值
  13. {
  14. i_up = (i+4)*i_up_1 + i_up_2;
  15. if(i_up%i_down == 0)return (i_up/i_down);
  16. }
  17. return 0;
  18. }
  19. int main()
  20. {
  21. int people_max = 5;
  22. int fish_get_last = 1;
  23. printf("最少是%d条\n",Fish_amount_speed(people_max));
  24. for (int i = 0;i < people_max;i++)
  25. {
  26. printf("第%d个人拿走了
  27. %d条\n",i+1,((fish_cnt_min-1)/5));
  28. fish_cnt_min = (fish_cnt_min-1)/5 * 4;
  29. }
  30. return 0;
  31. }

结果输出:


最少是3129条
第1个人拿走了 625条
第2个人拿走了 499条
第3个人拿走了 399条
第4个人拿走了 319条
第5个人拿走了 255条

------------------------------------------------------------------------------------------------------------------

  1. int []res= newint[5];
  2. int count = 1;
  3. for(int i =5;i<=10000;i++){
  4. int temp_var = 0;
  5. for(int j =0;j<5; j++){
  6. if(j == 0){
  7. if( (i-1)*4%5 ==0 ){
  8. temp_var = (i-1)*4/5;
  9. res[j] = i - 1 - temp_var;
  10. }else{
  11. break;
  12. }
  13. }else{
  14. if( (temp_var-1)*4%5 ==0 ){
  15. int temp_var1 = (temp_var-1)*4/5;
  16. res[j] = temp_var - 1 - temp_var1;
  17. temp_var = temp_var1;
  18. }else{
  19. break;
  20. }
  21. }
  22. if(j == 4){
  23. System.out.println("************答案"+(count++)+"************");
  24. System.out.println("共钓到鱼的总数:"+i+",剩余鱼的总数:"+temp_var);
  25. for(int p =0; p<5 ;p++){
  26. System.out.println("第"+(p+1)+"个人,拿走了"+res[p]+"条鱼");
  27. }
  28. }
  29. }
  30. }

 

--------------------------------------------------------------------------------------------------------------

  1. int CalcFishes(int numFishers)
  2. {
  3. int i = 0;
  4. int start = 7, totalFishes;
  5. totalFishes = start;
  6. while(i < numFishers)
  7. {
  8. if((totalFishes+1) % 4 == 0)
  9. {
  10. totalFishes = (totalFishes+1)/4 * 5;
  11. ++i;
  12. }
  13. else
  14. {
  15. start += 4;
  16. totalFishes = start;
  17. i = 0;
  18. }
  19. }
  20. return totalFishes+1;
  21. }
  22. int main(void)
  23. {
  24. printf("Total fishes: %d\n", CalcFishes(5));
  25. return 0;
  26. }

 

还有好多回复以及原文点击下面的链接

原文链接

 

 

原创粉丝点击