本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
12名海盗在一个小岛上发现了大量的金币,后统计一共有将近5万枚。
登上小岛是在夜里,天气又不好。由于各种原因,有的海盗偷拿了很多,有的拿了很少。
后来为了“均贫富”,头目提出一个很奇怪的方案:
每名海盗都把自己拿到的金币放在桌上。然后开始一个游戏。
金币最多的海盗要拿出自己的金币来补偿其他人。
补偿的额度为正好使被补偿人的金币数目翻番(即变为原来的2倍)。
游戏要一直进行下去,直到无法完成。
(当金币数最多的不只一个人或最多金币的人持有金币数不够补偿他人的)
游戏就这样紧张地进行了,一直进行了12轮,恰好每人都“放血”一次,
更离奇的是,刚好在第12轮后,每个人的金币数居然都相等了!! 这难道是天意吗?
请你计算,游戏开始前,所有海盗的初始金币数目,从小到大排列,中间有一个空格分开。
答案形如:
8 15 29 58 110 ...
当然,这个不是正确答案。
//最多金币海盗补偿的是所有金币比他少的海盗,不是只补偿一个海盗
逆推:例
最后一轮:2???????? 2 ????????2 ????????2 ????????2 ????????2 ????????2 ????????2 ????????2 ????????2 ????????2 ????????2?
则上一轮:1? ? ? ? ?1? ? ? ? ?1? ? ? ? ?1? ? ? ? ?1? ? ? ? ?1? ? ? ? ?1? ? ? ? ?1? ? ? ? ?1? ? ? ? ?1? ? ? ? ?1? ? ? ? 13
import java.util.Arrays;
public class main {
public static void main(String[] args) {
int[] jinbi=new int[12];
for(int i=12;i<50000;i+=12){//i为第12轮后的总金币数,为12的倍数
Arrays.fill(jinbi,i/12);
f(jinbi,i,11);
}
}
public static void f(int[] jinbi,int sum,int max){
//sum为金币总数,max为当前金币数最多的那个海盗的下标
if(max<0){
for(int i=11;i>=0;i--){
System.out.printf(jinbi[i]+" ");
}
return;
}
int count=0;
for(int i=0;i<12;i++){
if(i==max){
//如果i下标为金币数最多的那个海盗,则跳出一次循环,因为最多金币海盗不补偿自己
continue;
}
if(jinbi[i]%2!=0){
//如果第i个海盗的金币数不能被2整数,则返回函数,循环下一个总金币数
return;
}
else {
jinbi[i]=jinbi[i]/2;//逆推,上一轮的金币数为本轮金币数的一半
count+=jinbi[i];//记录最多金币的海盗一共要补偿多少金币
}
}
jinbi[max]=sum-count;//总金币数减去补偿金币的总数得到上一轮最多金币海盗的金币数
f(jinbi,sum,max-1);
}
}