题解:洛谷 P2669 金币

【题目来源】

洛谷:P2669 [NOIP 2015 普及组] 金币 - 洛谷

【题目描述】

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

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

【输入】

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

【输出】

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

【输入样例】

6

【输出样例】

14

【核心思想】

  1. 问题分析:给定天数 \(k\),工资发放模式为:第1天发1枚,接下来2天每天发2枚,接下来3天每天发3枚,以此类推。求前 \(k\) 天累计获得的金币总数。这是一个双重循环模拟问题。

  2. 算法选择

    • 外层枚举周期\(i\) 表示当前周期每天发放 \(i\) 枚金币,持续 \(i\)
    • 内层枚举天数\(j\)\(1\)\(i\),每天累加 \(i\) 枚金币
    • 提前终止:当累计天数 day == k 时立即输出结果并结束程序
  3. 关键步骤

    • 读入数据cin >> k
    • 初始化day = 0, ans = 0
    • 外层循环\(i\)\(1\)\(10000\)):枚举每个发放周期
      • 内层循环\(j\)\(1\)\(i\)):枚举周期内的每一天
        • ans += i:每天增加 \(i\) 枚金币
        • day++:累计天数加1
        • day == k:输出 ansreturn 0
    • 输出结果:前 \(k\) 天累计金币数
  4. 时间/空间复杂度

    • 时间复杂度:\(O(\sqrt{k})\),因 \(1+2+\cdots+n \approx \frac{n^2}{2}\),达到 \(k\) 天需要约 \(\sqrt{2k}\) 个周期
    • 空间复杂度:\(O(1)\),仅需常数个变量
  5. 周期模拟的核心思想

    • 嵌套周期结构:外层控制每天发放的金币数 \(i\),内层控制该金币数持续的天数 \(i\),形成"第 \(i\) 个周期持续 \(i\) 天、每天 \(i\) 枚"的模式
    • 即时终止优化:无需预先计算完整周期,达到 \(k\) 天立即停止,避免多余计算
    • 累加而非乘积:不直接用公式 \(i \times i\),而是逐天累加,便于在任意天终止
    • 适用于周期累加、嵌套循环模拟、提前终止类入门问题

【算法标签】

入门 #数学

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int k, day, ans;
int main()
{
	cin >> k;  //输入k
	for (int i=1; i<=10000; i++) {  // 枚举“之后i天”,如“之后2天”,“之后3天”
	    for (int j=1; j<=i; j++) {  // 枚举i天
	        ans += i;  // 每天金币数增加i
	        day++;  // 第day天
	        if (day==k) {  // 如果达到第k天,输出结果,并结束程序
	            cout << ans << endl;
	            return 0;
	        }
	    }
	}
	return 0;
}

【运行结果】

6
14
posted @ 2026-08-05 15:45  团爸讲算法  阅读(28)  评论(0)    收藏  举报