3
2 2 4
1、偶数个糖:这里偶数个糖可分为两部分分别是:
? I、初始化赋值为偶数
II、老师额外分配为偶数(num++);
2、分糖:将一半的糖分给左手边的孩子:
? I、简化为直接分给下一个小孩 ;
? II、每个小孩的糖数分一半给下一个并且从上一个小孩那得到他的一半糖;
? i)是先从别人那得到他的一半糖后,再将现在的糖数分一半给下一个人,,还是所有人先分一半糖出来,每个人都前一个人那拿走他的一半糖?(这两种计算方式结果不同,也是本题解题关键;简化后即:先 + 再 / 还是先 / 再 + );
3、判断糖数是否相等:
? I、不相等,跳转到第一条第二点(1.II),向下执行,
? II、相等,跳出循环,输出num;
#include <stdio.h>
#define N 100
void main() {
int i, n, num = 0, a[N], t;
scanf("%d", &n);
for (i = 0; i < n; i++) {//
scanf("%d", &a[i]);
}
for (;;) {
for (i = 1; i < n; i++) {//i从1开始,表示a[0]直接判断与a[1]是否相等,跳过a[0]与a[0]比较;
if (a[0] != a[i]) {
break;//如果第一个小孩糖的数量与其他小孩糖的数量不相等,跳出for循环,往下执行
}//如果没有进入if判断语句,说明所有小孩糖数相等,for循环从1执行到n-1;
}
if (i == n) {//接上for循环,当for循环执行完了以后,进行的操作是i++,此时i = n;所以可以拿来作为结束外循环条件;
break;//跳出外层循环
}
for (i = 0; i < n; i++) {//判断是否有奇数个糖,奇数+1,偶数不变;
if (a[i] % 2 == 1) {
a[i]++;
num++;
}
}
t = a[n - 1];//下面分糖实按从后向前遍历,因此最后一个小孩的糖数在最开始就会改变,无法给第一个小孩赋值,因此需要保存下来;
for (i = n - 1; i > 0; i--) {//,分糖(除以2)、得糖(+前一个人的1/2);
a[i] = a[i] / 2 + a[i - 1] / 2;
}
a[0] = a[0] / 2 + t / 2;//给第一个同学实现分糖、得糖;
}
printf("%d", num);
}
其中,在分糖和得糖那步可以实现小的优化:
前面代码不变,在判断奇偶时让所有同学的糖数一分为二;
for ( i = 0; i < n; i++)
{
if (a[i]%2==1)
{
a[i]++;
sum++;
}
a[i] /= 2;
}
temp = a[n - 1];
for ( i = n-1; i >0; i--)
{
//a[i] = a[i] / 2 + a[i - 1] / 2;
a[i] += a[i - 1];
}
//a[0] = a[0] / 2 + temp / 2;
a[0] += temp;
}
原文:https://www.cnblogs.com/destiny-2015/p/11804430.html