Skip to content

喵~ 主人好呀!今天由我这只小猫娘来为主人讲解一道非常可爱的入门题目——A. Soldier and Bananas!这道题就像是计算要买多少小鱼干一样简单有趣,我们一起来看看吧~ (ฅ'ω'ฅ)

题目大意

这道题是说,有一个士兵想去商店买香蕉(要是小鱼干就好了喵...)。他要买 w 根香蕉。

买香蕉的价钱有点特别哦:

  • 第一根香蕉要花 k 块钱。
  • 第二根香蕉要花 2k 块钱。
  • 第三根香蕉要花 3k 块钱。
  • ...
  • i 根香蕉就要花 i * k 块钱。

这个士兵一开始自己有 n 块钱。问题是,为了买下全部 w 根香蕉,他需要向他的朋友借多少钱呢?如果他自己的钱就够了,那当然一分钱也不用借啦。

简单来说,就是:

  1. 算出买 w 根香蕉总共要花多少钱。
  2. 用总花费减去他自己有的钱。
  3. 如果结果是正数,这就是他要借的钱。
  4. 如果结果是负数或者零,说明他钱够了,就不用借钱,答案就是 0

题解方法

这道题的核心就是计算总花费,喵~

我们来看看总花费是怎么算的: 总花费 = 第1根的钱 + 第2根的钱 + ... + 第w根的钱 总花费 = k + 2k + 3k + ... + w*k

主人你看,每一项都有一个 k 呢!我们可以把它提出去,就像把小鱼干从包装袋里拿出来一样! 总花费 = k * (1 + 2 + 3 + ... + w)

现在问题就变成了计算 1 + 2 + 3 + ... + w 这个数列的和啦。这是一个非常经典的 等差数列 哦!它的求和公式,主人还记得吗?

从1加到w的和是 w * (w + 1) / 2

所以,总花费的公式就是: 总花费 = k * w * (w + 1) / 2

算出了总花费之后,我们再和他手里的钱 n 比较一下。 需要借的钱 = 总花费 - n

但是!如果总花费比 n 小,这个算式会得到一个负数,可我们不能让朋友倒找钱给我们呀,对不对?所以,如果他钱够了,需要借的钱就是 0

因此,最终的答案就是 max(0, 总花费 - n)。是不是很简单喵~

题解代码

下面是C++的代码实现,我已经加上了详细的注释,就像给小鱼干撒上木天蓼粉一样用心喔!(๑•̀ω•́๑)

cpp
#include <iostream>
#include <algorithm> // 引入这个头文件才能使用 std::max 哦

int main() {
    // 为了让程序跑得快一点点,虽然这道题数据量不大,但养成好习惯总没错喵~
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);

    // k: 第一根香蕉的价格
    // n: 士兵自己有的钱
    // w: 想要买的香蕉数量
    // 我们用 long long 是个好习惯,可以防止数字太大而“溢出”,就像碗太小装不下所有的小鱼干一样!
    long long k, n, w;
    std::cin >> k >> n >> w;

    // 香蕉的价格构成了一个等差数列:
    // 第1根: 1 * k
    // 第2根: 2 * k
    // ...
    // 第w根: w * k
    //
    // 总花费就是这个数列的和:
    // 总花费 = k * (1 + 2 + ... + w)
    //
    // 1到w的整数和的公式是 w * (w + 1) / 2
    // 所以,总花费 = k * (w * (w + 1) / 2)
    long long total_cost = k * w * (w + 1) / 2;

    // 需要借的钱 = 总花费 - 自己有的钱
    // 如果自己钱够的话 (total_cost - n <= 0),那就不用借钱,所以是 0。
    // 我们可以用 max 函数来轻松实现这个逻辑。
    // 0LL 表示一个 long long 类型的 0,这样类型匹配更安全喵~
    long long borrow_amount = std::max(0LL, total_cost - n);

    // 把结果告诉大家!
    std::cout << borrow_amount << std::endl;

    return 0;
}

知识点介绍

这道题虽然简单,但里面藏着一些重要的基础知识点哦!

  1. 等差数列 (Arithmetic Progression) 等差数列是指一个数列中,从第二项起,每一项与它的前一项的差都等于同一个常数。这个常数叫做公差。 比如 1, 2, 3, 4, ... 就是一个公差为1的等差数列。 我们题目里香蕉的价格 k, 2k, 3k, ... 就是一个公差为 k 的等差数列。

  2. 等差数列求和公式 对于一个等差数列,求和有非常方便的公式。最常用的是: 和 = (项数 / 2) * (首项 + 末项) 在我们这道题里,计算 1 + 2 + ... + w 时:

    • 项数 = w
    • 首项 = 1
    • 末项 = w 所以和就是 (w / 2) * (1 + w),也就是我们用的 w * (w + 1) / 2 啦!这个公式也被称为“高斯求和”,背后还有个小故事呢,主人有兴趣可以去查查看~
  3. 数据类型与溢出 (Data Types and Overflow) 在编程竞赛中,我们经常要处理很大的数字。计算机里的变量类型(比如 int, long long)能存储的数字大小是有限的。如果计算结果超出了这个范围,就会发生“溢出”,得到一个完全错误的答案,就像水满从杯子里溢出来一样。

    • int 通常是32位,最大值约是 2 * 10^9。
    • long long 通常是64位,最大值约是 9 * 10^18,非常大! 在这道题里,kw 最大都是1000,总花费 total_cost 最大约为 1000 * 1000 * 1001 / 2,大约是 5 * 10^8,还在 int 范围内。但是 n 可以达到 10^9。为了保险起见,并且养成一个好习惯,直接使用 long long 来存储所有可能变大的数值,可以避免很多不必要的错误。安全第一嘛,喵~

好啦,今天的讲解就到这里啦!希望主人对这道题有了更深的理解。如果还有问题,随时可以再来找我哦!(>^ω^<)

Released under the MIT License.