1. 问题描述:
有n个小朋友围坐成一圈。老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏:
每个小朋友都把自己的糖果分一半给左手边的孩子。
一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而变成偶数。
反复进行这个游戏,直到所有小朋友的糖果数都相同为止。
你的任务是预测在已知的初始糖果情形下,老师一共需要补发多少个糖果。
输入
程序首先读入一个整数N(2< N< 100),表示小朋友的人数。
接着是一行用空格分开的N个偶数(每个偶数不大于1000,不小于2)
输出
要求程序输出一个整数,表示老师需要补发的糖果数。
样例输入
3
2 2 4
样例输出
4
2. 思路分析:
① 分析题目可以知道我们可以使用代码来模拟整个的过程,我们可以这样想:声明一个数组,数组中存放的是控制台输入的数据,从下标0开始遍历整个数组,遍历到倒数第二个元素为止,先把当前数组的元素值除以2,然后把比自己下表大1的元素除以2再加到自己的身上,然后其中需要特别处理的元素为数组的最后一个元素,因为它先要自己分一半给别人,而且它还要从下表为零的元素获取一半
② 其中在循环中判断当前遍历到的元素在操作完之后是否为奇数,假如是奇数那么需要计数加1,然后数组本身的元素加1,同样对于数组的最后一个元素也需要进行同样的判断,在一轮分完和补完糖之后那么需要判断当前数组中的元素值是否相同,若相同了,直接输入计数变量的值,然后return就好了
总结一下:主要是模拟整个过程然后注意一下边界元素的处理即可
3. 具体的代码如下:
import java.util.Scanner;
public class Main {
static int count = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n];
for(int i = 0; i < n; i++){
arr[i] = sc.nextInt();
}
sc.close();
while(true){
int t = arr[0];
for(int i = 0; i <= n - 2; i++){
arr[i] /= 2;
arr[i] += (arr[i + 1] / 2);
//判断是否是奇数
if((arr[i] & 1) == 1) {
count++;
arr[i]++;
}
}
//特别处理数组的最后一个元素
arr[n - 1] /= 2;
arr[n - 1] += (t / 2);
if((arr[n - 1] & 1) == 1){
count++;
arr[n - 1]++;
}
if(check(arr)){
System.out.println(count);
return;
}
}
}
private static boolean check(int[] arr) {
int t = arr[0];
for(int i = 1; i < arr.length; i++){
if(arr[i] != t) return false;
}
return true;
}
}