【NOIP 2015 普及组】金币

文章目录

  • 题目描述
  • 思路分析
  • 评价

题目描述

国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天)里,每天收到两枚金币;之后三天(第四、五、六天)里,每天收到三枚金币;之后四天(第七、八、九、十天)里,每天收到四枚金币 … … 这种工资发放模式会一直这样延续下去:当连续 n n n 天每天收到 n n n 枚金币后,骑士会在之后的连续 n + 1 n+1 n+1 天里,每天收到 n + 1 n+1 n+1 枚金币( n n n 为任意正整数)。

你需要编写一个程序,确定从第一天开始的给定天数内,骑士一共获得了多少金币。

时间限制:1 s
内存限制:128 MB

  • 输入
    一个正整数,表示天数。范围 1 1 1 10000 10000 10000
  • 输出
    骑士获得的金币数。
  • 样例输入
    6
    
  • 样例输出
    14
    

思路分析

乍看之下,此题可以用双层循环来解决。这里没有什么理论分析,我们直接讲代码。

首先定义一个计数器变量 coin,初始值为 1 1 1,用于表示每天需要发放给骑士的金币数量。另设一个累加器变量 total,初始值为 0 0 0,用于表示骑士获得的金币总数。

然后用外层循环来记录已发放金币的总天数,用内层循环来发放金币,当然了,内层循环也需要控制已发放金币的总天数。具体来讲,每发放一次金币,就需要累加一天。在下面的代码中,变量 iday 都是用来记录天数的,i 用来记录 coin 枚金币发放的天数,day 用来记录已发放金币的总天数。每当内层循环结束之后,coin 的值需要加一。

/** Name: coin1.cpp* Problem: 金币* Author: Teacher Gao.* Date&Time: 2024/03/07 23:26*/#include <iostream>using namespace std;int main()
{int n;cin >> n;int total = 0, coin = 1;for (int day = 1; day <= n; ) {for (int i = 1; i <= coin && day <= n; i++) {total += coin;day++;}coin++;}cout << total << endl;return 0;
}

仔细研究题目描述之后,不难发现国王每天给骑士发放的金币熟练呈现如下规律:
1 2 2 3 3 3 4 4 4 4 5 5 . . . \begin{matrix} 1 \\ 2 & 2 \\ 3 & 3 & 3 \\ 4 & 4 & 4 & 4 \\ 5 & 5 & ... \end{matrix} 12345234534...4

也就是说,金币总数为 t o t a l = 1 2 + 2 2 + 3 2 + . . . + k 2 + d total = 1^2 + 2^2 + 3^2 + ... + k^2 + d total=12+22+32+...+k2+d,其中 d d d 的值需要分情况讨论。这个式子表明,国王已经发放了 d a y = 1 + 2 + 3 + . . . + k = k × ( k + 1 ) 2 day = 1 + 2 + 3 + ... + k = \frac{k \times (k + 1)}{2} day=1+2+3+...+k=2k×(k+1) 天的金币。若 n = d a y n = day n=day,那么接下来就不需要发放金币了,即 d = 0 d = 0 d=0。否则,剩余的 n − d a y n - day nday 天国王每天需要给骑士发放 k + 1 k + 1 k+1 枚金币,那么 d = ( n − d a y ) × ( k + 1 ) d = (n - day) \times (k + 1) d=(nday)×(k+1),这里我们假设 n − d a y < k + 1 n - day < k + 1 nday<k+1

于是,我们可以用一个循环来枚举 k k k,并用 d a y day day n n n 的大小来控制循环。具体来说,若 d a y ≤ n day \le n dayn(事实上, d a y < n day < n day<n 也是正确的,请自行分析),那么就将 k 2 k^2 k2 累加到 t o t a l total total 中,否则就结束循环。并在循环结束后,将 ( n − d a y ) × ( k + 1 ) (n - day) \times (k + 1) (nday)×(k+1) 累加到 t o t a l total total 中。

分析到此就先告一段落。接下来我们讲讲代码中的细节,我们用变量 n 不断地减去 k,来代替每次将 k 累加到 day 中。于是循环条件可以写成 k <= n(写成 k < n 也是正确的,可以自行分析),(n - day) * (k + 1) 可以写成 n * k。之所以写成 n * k 而不是 n * (k + 1),是因为在代码中我们将 k 的初始值设为了 1 1 1,并且在累加完 total 之后才进行 k++,也就是说每次循环结束后,k 的值都是下一次需要发放的金币数量。此外,这种写法也导致了 n -= kk++ 两行代码的顺序不能调换,若要调换,则需把 n -= k 改写为 n -= k - 1

/** Name: coin2.cpp* Problem: 金币* Author: Teacher Gao.* Date&Time: 2024/03/07 23:30*/#include <iostream>using namespace std;int main()
{int n;cin >> n;int total = 0, k = 1;while (k <= n) {total += k * k;n -= k;k++;}total += n * k;cout << total << endl;return 0;
} 

基于上述分析,我们可以得到不等式 d a y = k × ( k + 1 ) 2 ≤ n day = \frac{k \times (k + 1)}{2} \le n day=2k×(k+1)n,即 k 2 + k − 2 n ≤ 0 k ^2 + k - 2 n \le 0 k2+k2n0。用求根公式可以求得方程 x 2 + x − 2 n = 0 x^2 + x - 2 n = 0 x2+x2n=0 的正根 x 1 = − 1 + 1 + 8 n 2 x_1 = \frac{-1 + \sqrt{1 + 8 n}}{2} x1=21+1+8n ,于是 k = ⌊ x 1 ⌋ k = \lfloor x_1 \rfloor k=x1

求出 k k k 之后,只需求出 t o t a l = 1 2 + 2 2 + 3 2 + . . . + k 2 + d total = 1^2 + 2^2 + 3^2 + ... + k^2 + d total=12+22+32+...+k2+d 即可,其中 d = ( n − d a y ) × ( k + 1 ) d = (n - day) \times (k + 1) d=(nday)×(k+1)。至于 ∑ i = 1 k i 2 = 1 2 + 2 2 + 3 2 + . . . + k 2 \sum_{i = 1}^{k} i^2 = 1^2 + 2^2 + 3^2 + ... + k^2 i=1ki2=12+22+32+...+k2,可以用公式 ∑ i = 1 k i 2 = n × ( n + 1 ) × ( 2 n + 1 ) 6 \sum_{i = 1}^{k} i^2 = \frac{n \times (n + 1) \times (2n + 1)}{6} i=1ki2=6n×(n+1)×(2n+1) 直接求出,该求和公式可以参考博主的博文关于和式的探讨(4)—— 一般性的方法。不过需要注意下面程序中对此公式的改写,主要目的是为了防止计算过程的溢出。

/** Name: coin3.cpp* Problem: 金币* Author: Teacher Gao.* Date&Time: 2024/03/07 23:38*/#include <iostream>
#include <cmath>using namespace std;int main()
{int n;cin >> n;int k = (sqrt(1 + 8 * n) - 1) / 2;int total = k * (k + 1) / 2 * (2 * k + 1) / 3;total += (n - k * (k + 1) / 2) * (k + 1);cout << total << endl;return 0;
} 

评价

此题的优秀之处在于,融合了诸如一元二次方程、向下取整等数学知识的同时,也确保了那些数学基础较弱的选手通过循环嵌套的方式进行求解。

不过循环嵌套的代码并没有那么容易写清楚。博主在教学过程中发现,绝大多数学生可以想到循环嵌套的方式,其中一部分学生会发现该程序只能计算诸如 n = 1 , 3 , 6 , 10 , . . . n = 1, 3, 6, 10,... n=1,3,6,10,... 之类的三角形数的答案,当 n n n 的值介于两个三角形数之间时,即 k − 1 < n ≤ k k - 1 < n \le k k1<nk 时,计算结果总是 k k k 对应的结果。这是因为内层循环没有控制变量 day 的值,以至于 day 的值会超出 n n n 的范围。

可以想到第二种做法的学生,博主在教学过程中只发现了少数几个,而且这少数的几个学生都是奥数成绩不错的学生。至于第三种做法,目前尚且没有见到学生独立写出来过。

此题有着较好的区分度,以及开放性的解题方式,考察维度很立体。容易想到的循环嵌套方法,并不容易写清楚代码;容易写代码的数学方法,并不容易弄清楚代码中的细节。但是只要学生在逻辑思维和数学思维中有一方面较为突出,就可以解出此题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/740445.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:RichText)

富文本组件&#xff0c;解析并显示HTML格式文本。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。该组件无法根据内容自适应设置宽高属性&#xff0c;需要开发者设置显示布局。 子组件 不包含子组…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的石头剪刀布手势识别系统详解(深度学习模型+UI界面代码+训练数据集)

摘要&#xff1a;本篇博客深入探讨了使用深度学习技术开发石头剪刀布手势识别系统的过程&#xff0c;并分享了完整代码。该系统利用先进的YOLOv8、YOLOv7、YOLOv6、YOLOv5算法&#xff0c;并对这几个版本进行性能对比&#xff0c;如mAP、F1 Score等关键指标。文章详细阐述了YOL…

西门子S7.NET通信库【读】操作详解

在使用西门子PLC进行工业自动化控制的过程中&#xff0c;经常需要与PLC进行数据交换。S7.NET是一款广泛应用于.NET平台的西门子PLC通信库&#xff0c;它为开发者提供了一系列的API函数&#xff0c;以便在C#、VB.NET等.NET语言中轻松实现与西门子PLC的数据交互。本文将详细介绍如…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的远距离停车位检测系统(深度学习代码+UI界面+训练数据集)

摘要&#xff1a;开发远距离停车位检测系统对于提高停车效率具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个远距离停车位检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0c;展示了不…

2.MySQL中的数据类型

整数类型&#xff1a; tinyint(m): 1个字节 范围(-128~127) 常用&#xff1a;性别 0和1表示性别&#xff1b;状态 0和1表示 int(m): 4个字节 范围(-2147483648~2147483647) 常用&#xff1a;数值 数值类型中的长度m是值显示长度&#xff0c;只有字段指定zerofill时有用 例如…

TS271IDT运算放大器芯片中文资料PDF数据手册引脚图图片参数价格功能

产品描述&#xff1a; TS271 是一款低成本、低功耗的单通道运算放大器&#xff0c;设计用于采用单电源或双电源供电。该运算放大器采用意法半导体硅栅CMOS工艺&#xff0c;具有出色的消耗-速度比。该放大器非常适合低功耗应用。 电源可通过引脚 8 和 4 之间连接的电阻器进行外…

解决git clone报错RPC failed; curl 56 GnuTLS recv error (-9)

一、问题描述 ubuntu终端输入&#xff1a;git clone https://github.com/ARISE-Initiative/robomimic.git 报错内容如下&#xff1a; Cloning into robomimic... remote: Enumerating objects: 3751, done. remote: Counting objects: 100% (1235/1235), done. remote: Comp…

2024年【高压电工】考试及高压电工考试总结

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 高压电工考试考前必练&#xff01;安全生产模拟考试一点通每个月更新高压电工考试总结题目及答案&#xff01;多做几遍&#xff0c;其实通过高压电工模拟试题很简单。 1、【单选题】 为了保证频率偏差不超过规定值,必…

webpack一些常用的Loader和Plugin

文章目录 webpack4一些常用的Loader&#xff1a;webpack4一些常用的Plugin&#xff1a;关于webpack5的一些特点&#xff1a;新增特性&#xff1a;修复的问题&#xff1a;内置模块和工具&#xff1a; 关于webpack5的一些内置:内置Loader&#xff1a;内置Plugin&#xff1a; webp…

基于Springboot的预报名管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的预报名管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&a…

用miniconda建立PyTorch、Keras、TensorFlow三个环境

一、配置清华镜像conda源 由于网络问题&#xff0c;直接使用conda默认的源下载包可能会非常慢。为了解决这个问题&#xff0c;可以配置国内镜像源来加速包的下载。清华大学TUNA协会提供了一个常用的conda镜像源。下面是如何配置清华镜像源的步骤&#xff1a; 1. 配置清华conda…

发布DDD脚手架到Maven仓库,IntelliJ IDEA 配置一下即可使用

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 项目&#xff1a;https://gaga.plus 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 大家好&#xff0c;我是技术UP主&#xff0c;小傅哥。 这篇文章将帮助粉丝伙伴们更高效地利…

使用 Jenkins 和 Spinnaker 构建 Kubernetes CI/CD

无论您是新手还是持续集成和持续交付以及容器化领域的经验丰富&#xff0c;本文都将为您提供设置 Spinnaker 以满足您的软件应用程序交付需求的基本知识。 了解 Jenkins、Spinnaker 和 Kubernetes Kubernetes 和 Jenkins 是两个强大的工具&#xff0c;它们相互配合&#xff0…

Head First Design Patterns - 命令模式

什么是命令模式 命令模式&#xff0c;把请求封装成对象&#xff0c;以便使用不同的请求、队列或者日志请求来参数化其他对象&#xff0c;并支持可撤回的操作。 为什么会有命令模式 假设要设置一个遥控器&#xff0c;遥控器需要控制多个设备&#xff0c;每个设备除了开关&#…

uniapp微信小程序 隐藏顶部导航栏 路由跳转带参数

隐藏单页顶部导航栏和左上角返回按钮&#xff0c;在pages.json里配置 {"path": "pages/gameLogin/gameLogin","style": {"navigationStyle":"custom","app-plus":{"titleView":false}} } 路由跳转 u…

ARM64汇编06 - 基本整型运算指令

ADD (immediate) 将 Xn 与 imm 相加&#xff0c;结果赋值给 Xd&#xff0c;imm 是无符号数&#xff0c;范围为 0 - 4095。 shift 是对 imm 进行移位&#xff0c;shift 为 0 的时候&#xff0c;表示左移 0 位&#xff0c;即不变。shift 为 1 的时候&#xff0c;表示左移12 位&a…

Linux的MySQL安装与卸载

安装与卸载 卸载安装配置yum源安装MySQL 声明一下本人用的Linux版本是CentOs7.9版本的。 卸载 如果我们用的云服务器&#xff0c;云服务器可能会自带MySQL或者mariadb&#xff08;其实就是MySQL的一个开源分支&#xff09;&#xff0c;如果我们不想用自带的&#xff0c;需要先…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的水下目标检测系统(深度学习模型+UI界面+训练数据集)

摘要&#xff1a;本研究详述了一种采用深度学习技术的水下目标检测系统&#xff0c;该系统集成了最新的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5等早期算法进行了性能评估对比。该系统能够在各种媒介——包括图像、视频文件、实时视频流及批量文件中——准确地识别水…

【C++教程从0到1入门编程】第八篇:STL中string类的模拟实现

一、 string类的模拟实现 下面是一个列子 #include <iostream> namespace y {class string{public: //string() //无参构造函数// :_str(nullptr)//{}//string(char* str) //有参构造函数// :_str(str)//{}string():_str(new char[1]){_str[0] \0;}string(c…

图论(蓝桥杯 C++ 题目 代码 注解)

目录 迪杰斯特拉模板&#xff08;用来求一个点出发到其它点的最短距离&#xff09;&#xff1a; 克鲁斯卡尔模板&#xff08;用来求最小生成树&#xff09;&#xff1a; 题目一&#xff08;蓝桥王国&#xff09;&#xff1a; 题目二&#xff08;随机数据下的最短路径&#…