Skip to content

主人,你好呀~ 看到这道题是不是有点小困惑呢?没关系,让本猫娘来帮你分析一下,保证你一下子就明白啦,喵~ (ฅ'ω'ฅ)

题目大意

这道题讲的是一只叫做 Ilya 的小狮子,他有一个银行账户。账户余额可以是个负数,表示他欠银行钱啦。

Ilya 过生日的时候,银行送了他一个很棒的礼物:他可以对自己的账户余额进行一次操作,操作可以是下面两种中的任意一种:

  1. 删除余额的最后一位数字。
  2. 删除余额的倒数第二位数字。

当然,Ilya 也可以选择不使用这个礼物。

我们的任务就是,帮助对数学不太敏感的 Ilya 找到,通过这次操作(或者不操作),他能得到的最大的账户余额是多少。

举个栗子:如果他的余额是 -123

  • 删除最后一位 3,余额变成 -12
  • 删除倒数第二位 2,余额变成 -13。 在这两种情况里,-12-13 要大,所以 -12 是一个可能的更优结果。

解题思路

主人,要解决这个问题,我们得像小猫抓老鼠一样,分情况讨论,这样思路才清晰呢!关键就在于账户余额 n 是正数还是负数。

情况一:当 n 是非负数时 (n >= 0)

如果 Ilya 的账户里有钱或者正好是 0(比如 2230),那他肯定不希望钱变少,对吧?

你想想看,一个正数,比如 2230

  • 如果删除最后一位 0,就变成了 223
  • 如果删除倒数第二位 3,就变成了 220

223220 都比原来的 2230 小。所以,当账户余额是非负数的时候,任何删除操作都会让钱变少。最好的策略就是什么都不做!所以,直接输出原来的数字 n 就好啦。简单吧,喵~

情况二:当 n 是负数时 (n < 0)

这个情况稍微有点绕,但听我慢慢说哦。对于一个负数,我们想让它变得最大,其实就是想让它的绝对值变得最小。比如说,-10 就比 -100 要大,对吧?

题目保证了 |n| >= 10,所以负数至少有两位数(比如 -10-99)。从一个多位的负数中删除一个数字,它的绝对值一定会变小,从而使得整个数值变大。

例如,对于 -123

  • 删除最后一位得到 -12
  • 删除倒数第二位得到 -13

-12-13 都比 -123 大。所以,对于负数,我们必须执行一次删除操作才能得到最大值。

那么问题就变成了:删除最后一位和删除倒数第二位,哪种结果更大呢?我们只需要计算出这两种操作后的结果,然后取它们中较大的一个就可以啦!

  • 如何计算删除最后一位? 这个很简单,直接用整数除法 n / 10 就行。例如 (-123) / 10 在 C++ 中会得到 -12

  • 如何计算删除倒数第二位? 这个稍微复杂一点点。我们可以把它拆开看:

    1. 先把 n 的最后两位都去掉,得到 n / 100
    2. 再把 n 的最后一位取出来,得到 n % 10
    3. 然后把第一步的结果乘以 10(相当于左移一位),再加上第二步的结果。 公式就是 (n / 100) * 10 + (n % 10)。 我们还用 -123 来试试: (-123 / 100) -> -1(-123 % 10) -> -3 结果就是 (-1) * 10 + (-3) -> -10 - 3 -> -13。 完美!

最后,我们只需要比较 n / 10(n / 100) * 10 + (n % 10) 这两个结果,哪个大就输出哪个。比如在 -123 的例子里,我们比较 -12-13max(-12, -13) 就是 -12

题解

下面就是这份思路的 C++ 代码实现啦,本猫娘加了一些注释,方便主人理解哦~

cpp
#include <iostream>
#include <algorithm> // 我们需要用里面的 std::max 函数喵

int main() {
    // 这两行是为了让输入输出快一点,是竞赛里的小技巧呢
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);

    int n;
    std::cin >> n; // 读取 Ilya 的账户余额

    if (n >= 0) {
        // 情况一:如果 n 是非负数
        // 任何删除都会让数字变小,所以最好的选择是什么都不做
        std::cout << n << std::endl;
    } else {
        // 情况二:如果 n 是负数
        // 我们必须进行一次删除才能让数值变大(更接近0)

        // 选项1:删除最后一位数字
        // 整数除以10就可以做到啦
        int option1 = n / 10;

        // 选项2:删除倒数第二位数字
        // (n / 100) 是去掉末尾两位,再 * 10 是为了空出个位
        // (n % 10) 是取到最后一位
        // 两个加起来就拼接好了新数字
        int option2 = (n / 100) * 10 + (n % 10);

        // 使用 std::max 找出两个选项中较大的那个并输出
        std::cout << std::max(option1, option2) << std::endl;
    }

    return 0;
}

知识点介绍

这道题虽然简单,但里面用到的小知识点还是很有用的哦!

  1. 整数除法 (/) 和取模 (%) 运算符

    • a / 10:对于一个整数 a,除以 10 的结果会自动去掉小数部分,效果就是移除了 a 的最后一位数字。
    • a % 10:取 a 除以 10 的余数,效果就是得到了 a 的最后一位数字。
    • 对负数的处理:在 C++ 中,这两个运算符对负数的处理方式对我们非常有利。比如 -123 / 10 的结果是 -12-123 % 10 的结果是 -3。这种行为恰好符合我们构造新数字的需求。
  2. 条件判断 (if-else) 这是编程中最最基础的逻辑控制结构。通过判断一个条件(这里是 n >= 0),让程序根据不同的情况执行不同的代码块。这道题就是通过 if-else 把问题完美地分成了两种情况来处理。

  3. std::max 函数 这个函数来自 C++ 的 <algorithm> 头文件,非常方便。std::max(a, b) 会返回 ab 中较大的那个值。在我们需要比较并找出最大值的时候,用它能让代码看起来更简洁清晰,不用自己手写一个 if 判断啦。

好啦,主人,这次的讲解就到这里啦!是不是感觉很简单了呢?以后有什么问题随时可以再来找我哦,喵~ ( ´ ▽ ` )ノ

Released under the MIT License.