GESP二级的练习往往着重于基础算法与逻辑思维能力的培养。今天,我们一起来攻克一道关于幂运算末尾数字的经典题目——Luogu B2075 幂的末尾,通过这道题深入理解取模运算和循环的应用。
这道题被归类为“多层循环和分支练习”,难度两颗星,非常适合用来巩固C++编程基础。
题目要求
题目描述
幂 $a^b$ 的末三位数是多少?
输入格式
两个正整数 $a$, $b$。$1 \\le a \\le 10^4$,$1 \\le b \\le 10^4$。
输出格式
从高位到低位输出幂的末三位数字,中间无分隔符。若幂本身不足三位,在前面补零。
输入样例 #1
2 3
输出样例 #1
008
解释:$2^3=8$,不足三位,因此输出 008。
输入样例 #2
7 2011
输出样例 #2
743
题目分析与解题思路
看到题目,你的第一反应是不是直接计算 $a^b$?但当 $a$ 和 $b$ 都很大时(比如 $10000^{10000}$),这个数字会远远超出任何基本数据类型的表示范围,直接计算显然行不通。
那么,如何绕过这个“大数”难题呢?题目只关心最后三位数。这给了我们一个非常重要的提示:在计算过程中,我们完全可以只保留与最后三位相关的部分,而舍弃更高位。
这就是取模运算的用武之地。我们知道,一个数对 1000 取余,得到的结果就是它的最后三位。因此,核心思路是:
在模拟幂运算 $a^b$ 的过程中,每次乘法后都立即对结果取模 (mod 1000),这样我们始终只操作一个不超过 999 的数字,完美避开了大数问题。
具体实现步骤如下:
- 初始化:读入底数
a 和指数 b。设结果变量 ans = 1。
- 循环计算:执行
b 次循环。
- 在每次循环中,计算
ans = (ans * a) % 1000。
- 这相当于在不断累积相乘的同时,始终只保留结果的末三位。
- 格式化输出:循环结束后,
ans 即为 $a^b$ 的末三位数字(可能不足三位)。使用 printf(“%03d“, ans) 可以自动在不足三位的数字前补零,并输出三位数。
示例代码与逐行解析
下面是基于上述思路编写的C++代码:
#include <cstdio>
#include <iostream>
using namespace std;
int main() {
int a, b; // 定义底数a和指数b
cin >> a >> b; // 读入底数a和指数b
int ans = 1; // 初始化结果ans为1
for (int i = 1; i <= b; i++) { // 循环b次,模拟乘b次a
ans = (ans * a) % 1000; // 核心:相乘后立即取末三位
}
printf("%03d", ans); // 输出结果的3位数字,不足补0
return 0; // 程序正常结束
}
代码解析:
#include <cstdio> 引入了 printf 函数,用于格式化输出。
ans = 1 是乘法的单位元,任何数乘以1都不变。
for 循环精确执行 b 次,每一次都让当前的 ans 乘以 a,并立即通过 % 1000 取得新的末三位。
printf(“%03d“, ans) 是输出关键:%03d 表示以十进制整数输出,宽度为3位,不足3位时左侧用 0 填充。
通过这道题,我们不仅学会了一个巧妙的解题技巧(利用取模避免大数),也巩固了循环和格式化输出的基本语法。希望这个解析能帮助你更好地理解相关概念。如果你想与更多学习者交流探讨,欢迎访问云栈社区。
题目来源:
- “luogu-”系列题目可在洛谷题库进行在线评测。
- “bcqm-”系列题目可在编程启蒙题库进行在线评测。
|