zoukankan      html  css  js  c++  java
  • [蓝桥杯][2014年第五届真题]分糖果

    题目描述:

    问题描述:

    有n个小朋友围坐成一圈。老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏:

    每个小朋友都把自己的糖果分一半给左手边的孩子。

    一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而变成偶数。

    反复进行这个游戏,直到所有小朋友的糖果数都相同为止。

    你的任务是预测在已知的初始糖果情形下,老师一共需要补发多少个糖果。

    输入

    程序首先读入一个整数N(2< N< 100),表示小朋友的人数。 
    接着是一行用空格分开的N个偶数(每个偶数不大于1000,不小于2) 

    输出

    要求程序输出一个整数,表示老师需要补发的糖果数。

    样例输入

    3 
    2  2  4 

    样例输出

    4

    题意解析:

    1、偶数个糖:这里偶数个糖可分为两部分分别是:

    ​ I、初始化赋值为偶数  

    II、老师额外分配为偶数(num++);

    2、分糖:将一半的糖分给左手边的孩子:

    ​ I、简化为直接分给下一个小孩  ;

    ​ II、每个小孩的糖数分一半给下一个并且从上一个小孩那得到他的一半糖;

    ​ i)是先从别人那得到他的一半糖后,再将现在的糖数分一半给下一个人,,还是所有人先分一半糖出来,每个人都前一个人那拿走他的一半糖?(这两种计算方式结果不同,也是本题解题关键;简化后即:先 + 再 /  还是先 / 再 + );

    3、判断糖数是否相等:

    ​ I、不相等,跳转到第一条第二点(1.II),向下执行,

    ​ II、相等,跳出循环,输出num;

    图解2.II.i:

    代码实现:

    #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;
        }

  • 相关阅读:
    剑指 Offer 22. 链表中倒数第k个节点
    1221. 分割平衡字符串
    1528. 重新排列字符串
    1450. 在既定时间做作业的学生人数
    1266. 访问所有点的最小时间
    1572. 矩阵对角线元素的和
    使用Python进行数据传输
    分布式系统的原理与设计
    分布式缓存
    Centos6 配置最新yum源
  • 原文地址:https://www.cnblogs.com/destiny-2015/p/11804430.html
Copyright © 2011-2022 走看看