【蓝桥杯】 历届试题 分糖果(模拟)

2024-03-30 13:08

本文主要是介绍【蓝桥杯】 历届试题 分糖果(模拟),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

历届试题 分糖果

问题描述

n n n 个小朋友围坐成一圈。老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏:每个小朋友都把自己的糖果分一半给左手边的孩子。一轮分糖后,拥有奇数颗糖的孩子由老师补给 1 个糖果,从而变成偶数。
反复进行这个游戏,直到所有小朋友的糖果数都相同为止。
你的任务是预测在已知的初始糖果情形下,老师一共需要补发多少个糖果。

输入格式

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

输出格式

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

样例输入

3
2 2 4

样例输出

4



—— 踏雪寻梅 ——


大多说人看到这道题的时候其实都感觉挺简单的(当然,确实不难),反正就是模拟这个分糖以及发糖的过程嘛,最后统计补发糖果的数量即可。但是,在模拟发糖过程时,便会出现一些问题。

我第一次模拟先是建立了一个 int 型数组 c h i l d s childs childs 来存储每个小朋友所拥有的糖果数量,接着通过一个循环(初始值从最后一个开始),把当前的 c h i l d s [ i ] childs[ i ] childs[i] 赋值为 c h i l d s [ i ] / 2 childs[ i ] / 2 childs[i]/2 并加上 c h i l d s [ i − 1 ] / 2 childs[ i-1 ] / 2 childs[i1]/2,即: c h i l d s [ i ] = ( c h i l d s [ i ] + c h i l d s [ i − 1 ] ) / 2 childs[ i ] = ( childs[ i ] + childs[ i-1 ] ) / 2 childs[i]=(childs[i]+childs[i1])/2,最后再为第一个小朋友单独写交换糖果的代码。

但事实是,无论 i i i 初始从 1 开始还是从最后开始,总会出错!因为小朋友们在交换时,其实是一个环形结构,因此无论从那里作为切入口进去,都将错误地把当前切入的这个小朋友的糖果数默认为 c h i l d s [ i ] / 2 childs[ i ] / 2 childs[i]/2 。而实际上,这个小朋友的糖果数量应该为 c h i l d s [ i ] / 2 + c h i l d s [ i − 1 ] / 2 childs[ i ] /2 + childs[ i-1] / 2 childs[i]/2+childs[i1]/2(或者为 c h i l d s [ i ] / 2 + c h i l d s [ i + 1 ] / 2 childs[ i ] /2 + childs[ i+1] / 2 childs[i]/2+childs[i+1]/2)。

并且仔细一点的同学应该发现了,在循环中,当你执行完了某次 c h i l d s [ i ] = ( c h i l d s [ i ] + c h i l d s [ i − 1 ] ) / 2 childs[ i ] = ( childs[ i ] + childs[ i-1 ] ) / 2 childs[i]=(childs[i]+childs[i1])/2 后,对于下一次而言,其实这时的 c h i l d [ i ] child[ i ] child[i] 已经不再是初始的那个 c h i l d s [ i ] childs[ i ] childs[i] 了(当然, c h i l d s [ i − 1 ] childs[ i-1 ] childs[i1] 也类似)。因为当你的代码用到了这样的一个循环的时候,说明你已经默认这个分糖果的游戏是按序轮次一个一个进行的,而实际上,这个发糖的过程是所有小朋友同时开始分、发、接受的!(当然,理解错误有一部分是题目表意不明的原因)。

既然是同时发糖的,那么为何不多用两个数组来维护这个发糖的过程呢?因此,修正后的解题思路大致如下:

  • 步骤一:用一个数组 c h i l d s [ i ] childs[i] childs[i] 来存储初始情况下每个小朋友手上的糖果数,并建立两个数组 c l d 1 [ i ] cld1[i] cld1[i] c l d 2 [ i ] cld2[i] cld2[i] 用以维护之后的游戏过程。
  • 步骤二:模拟发糖过程(这是一重循环,结束条件即为所有小朋友的糖果都相同):
    • 通过一重循环将所有小朋友的糖果都除以 2 ,并将结果保存进入 c l d 1 [ i ] cld1[i] cld1[i] 中;
    • 通过一重循环把每个小朋友手上的糖果错位存储进 c l d 2 [ i ] cld2[i] cld2[i] 中(注:首位小朋友需要单独错位,即 c l d 2 [ 0 ] = c l d 1 [ N − 1 ] cld2[0]=cld1[N-1] cld2[0]=cld1[N1]);
    • 更新每个小朋友手上的糖果数量,即 c h i l d s [ i ] = c l d 1 [ i ] + c l d 2 [ i ] childs[i]=cld1[i]+cld2[i] childs[i]=cld1[i]+cld2[i]


—— 破云见雾 ——


下面给出基于以上思路的完整代码:

#include<iostream>
using namespace std;
int main()
{int N,i,childs[100],sum=0;int cld1[100],cld2[100];cin>>N;for(i=0;i<N;i++)cin>>childs[i];while(1){//二分处理for(i=0;i<N;i++)cld1[i]=childs[i]/2;for(i=1;i<N;i++)cld2[i]=cld1[i-1];cld2[0]=cld1[N-1];//合同处理for(i=0;i<N;i++)childs[i]=cld1[i]+cld2[i];int flag=childs[0];for(i=1;i<N;i++)if(childs[i]!=flag)break;//再次发糖if(i!=N){for(i=0;i<N;i++)if(childs[i]%2!=0)	//检测到需要发糖{childs[i]++;sum++;}}//退出else break;}cout<<sum<<endl;return 0;
}

END


这篇关于【蓝桥杯】 历届试题 分糖果(模拟)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/861568

相关文章

2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题是由安全生产模拟考试一点通提供,流动式起重机司机证模拟考试题库是根据流动式起重机司机最新版教材,流动式起重机司机大纲整理而成(含2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题参考答案和部分工种参考解析),掌握本资料和学校方法,考试容易。流动式起重机司机考试技

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

hdu4431麻将模拟

给13张牌。问增加哪些牌可以胡牌。 胡牌有以下几种情况: 1、一个对子 + 4组 3个相同的牌或者顺子。 2、7个不同的对子。 3、13幺 贪心的思想: 对于某张牌>=3个,先减去3个相同,再组合顺子。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOExcepti

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

【算法专场】模拟(下)

目录 前言 38. 外观数列 算法分析 算法思路 算法代码 1419. 数青蛙 算法分析 算法思路 算法代码  2671. 频率跟踪器 算法分析 算法思路 算法代码 前言 在前面我们已经讲解了什么是模拟算法,这篇主要是讲解在leetcode上遇到的一些模拟题目~ 38. 外观数列 算法分析 这道题其实就是要将连续且相同的字符替换成字符重复的次数+

模拟实现vector中的常见接口

insert void insert(iterator pos, const T& x){if (_finish == _endofstorage){int n = pos - _start;size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;reserve(newcapacity);pos = _start + n;//防止迭代

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT