当前位置: 首页 > news >正文

NOIP普及组系列【2015】 P2669 [NOIP 2015 普及组] 金币题解

题目背景

NOIP2015 普及组 T1

题目描述

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

请计算在前 k 天里,骑士一共获得了多少金币。

输入格式

一个正整数 k,表示发放金币的天数。

输出格式

一个正整数,即骑士收到的金币数。

输入输出样例

输入 #1复制

6

输出 #1复制

14

输入 #2复制

1000

输出 #2复制

29820

说明/提示

【样例 1 说明】

骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。因此一共收到 1+2+2+3+3+3=14 枚金币。

对于 100% 的数据,1≤k≤104。

问题重述

国王将金币作为工资发放给骑士,第一天1枚,随后两天每天2枚,接着三天每天3枚...即连续k天每天发放k枚金币。给定天数N,求总共发放的金币数。

解法一:模拟递推法

核心思路

通过循环模拟发放过程,维护当前阶段的天数计数和金币面值:

  1. 外层循环控制阶段更替(k值递增)

  2. 内层循环控制当前阶段的天数执行

  3. 实时累加金币并检测剩余天数

代码实现

#include <iostream>
using namespace std;int main() {int N, sum = 0, k = 1;cin >> N;while (N > 0) {int days = min(k, N);sum += days * k;N -= days;k++;}cout << sum << endl;return 0;
}

解法二:数学公式法

核心思路

通过数学推导直接计算:

  1. 找到最大的m满足m(m+1)/2 ≤ N

  2. 完整阶段金币和 = Σi² (i从1到m)

  3. 剩余天数金币 = (N - m(m+1)/2) * (m+1)

代码实现

#include <iostream>
#include <cmath>
using namespace std;int main() {int N;cin >> N;int m = (sqrt(8*N + 1) - 1) / 2;int sum = m*(m+1)*(2*m+1)/6;int remain = N - m*(m+1)/2;sum += remain * (m + 1);cout << sum << endl;return 0;
}

复杂度分析

  • 时间复杂度:O(1)

  • 空间复杂度:O(1)

对比总结

方法

优势

局限性

模拟递推法

逻辑直观易理解

大数据量时效率较低

数学公式法

计算效率极高

需要数学推导能力

建议初学者先掌握模拟法,再挑战公式法。实际竞赛中根据数据规模选择方法,当N≤1e6时两种方法均可,N≥1e9时优选公式法。

深度总结

这道看似简单的金币问题,实则蕴含着丰富的算法思维训练价值。作为NOIP普及组的经典题目,它完美展现了从暴力模拟到数学优化的思维跃迁过程。

从教学角度来看,模拟法是最符合人类直觉的解决方式。它通过逐日/逐周期模拟金币发放过程,帮助初学者建立问题与计算机实现的桥梁。这种方法虽然效率不是最优,但对于培养编程思维和问题分解能力至关重要。在实际教学中,建议要求学生先掌握这种基础解法,再引导其思考优化可能。

数学公式法则展现了算法竞赛的精髓——通过数学建模将问题抽象化。这里涉及三个关键数学知识点:等差数列求和、二次方程求解和平方和公式。特别是确定完整周期数m时,通过求解m(m+1)/2 ≤ N这个不等式,转化为二次方程求根问题,体现了数学工具在算法优化中的强大威力。

两种解法的时间复杂度对比极具教育意义:模拟法的O(√N)虽然比纯暴力O(N)优秀,但当N达到1e18量级时仍显不足;而公式法的O(1)特性则展现了数学的降维打击能力。这种对比能让学生深刻理解算法优化的价值。

从题目设计角度看,该问题巧妙地将数列知识与编程实现相结合。其变种经常出现在各类竞赛中,比如改为求第N天获得的金币数,或调整发放规则为斐波那契数列等。掌握这类问题的求解范式,对培养竞赛思维很有帮助。

最后需要特别注意的是数值溢出问题。当N较大时(如1e5),平方和可能超过int范围,在实际编程中应该使用long long类型。这也是NOIP比赛中常见的考查点之一。

通过这道题,我们不仅学到了两种具体解法,更重要的是理解了算法设计中的分层思维:从基础实现到数学优化,这是每个选手成长的必经之路。

http://www.dtcms.com/a/298673.html

相关文章:

  • GPU 驱动安装升级测试
  • 避开算力坑!无人机桥梁检测场景下YOLO模型选型指南
  • Minio Docker 集群部署
  • 【阅读整理】野火ADC_AD7192模块资料
  • haproxy七层代理(超详细)
  • 算法讲解--查找总价值为目标值的两个商品
  • MyBatisPlus简介与基本CRUD
  • 域名服务器的作用是什么
  • 【js(7)创建对象的三种写法】
  • Node.js(三)之Express
  • Three.js 动画系统入门:Tween.js 与 AnimationMixer 的使用
  • 习题5.6 “数学黑洞“
  • Java研学-RabbitMQ(二)
  • 亚德诺半导体AD8612ARUZ-REEL双通道精密运算放大器,0.5μV超低失调电压+0.02μV/°C温漂!
  • 老龄化浪潮下的破局者:智慧养老重塑银发经济格局
  • ptmalloc(glibc-2.12.1)源码解析2
  • 深入理解 UDP 协议:从原理到实战的技术解析
  • 开源语音TTS与ASR大模型选型指南(2025最新版)(疯聊AI提供)
  • Paimon主键表的合并机制
  • 模糊综合评估法简单示例
  • MySQL的认识与基本操作
  • NaVILA源码解析——从其VLA部分到其low-level部分:涵盖legged-loco、rsl_rl
  • AMD推出Radeon AI Pro R9700:32GB显存加持,发力AI推理与专业图形双场景
  • 13.使用C连接mysql
  • ro属性和persist属性的区别
  • 什么是游戏盾(高防版)?
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-24,(知识点:二极管基础知识,单向导电性)
  • Redux 入门超详细指南
  • vue3中pinia详解
  • 关于“前导零”的问题记录,也就是(0.1)和.1这种数据处理问题