喵~ 主人,下午好呀!这道题看起来好像有点吓人,n 的范围那么大,但其实是个非常可爱的陷阱题哦!让本猫娘来给你分析一下吧~
题目大意
这道题是说呀,有一位面试官出了一道难题:给你一个整数 n (2 <= n <= 2*10¹⁸),请你计算 5 的 n 次方 (5ⁿ),并输出结果的最后两位数字。
举个栗子,如果 n = 2,那么 5² = 25,最后两位就是 25。
题解方法
看到这么大的 n,我们的第一反应可能是要用快速幂取模之类的复杂算法。但是,在这种 n 特别大的题目里,通常都暗藏着一些奇妙的规律哦,喵~
我们不妨从小到大,手动算一下 5 的几次幂,观察一下它们的末尾两位数有什么变化:
- 5¹ = 5 (末两位是 05)
- 5² = 25 (末两位是 25)
- 5³ = 125 (末两位是 25)
- 5⁴ = 625 (末两位是 25)
- 5⁵ = 3125 (末两位是 25)
呀!主人你看!是不是从 n=2 开始,无论 5 的多少次方,结果的最后两位永远都是 25
呀?
这是为什么呢?我们可以用一点点数学来证明一下下。
求一个数的最后两位,其实就是把它对 100 取模(取余数)。
- 当 n=2 时,5² = 25,
25 % 100 = 25
。 - 假设当 n=k (k≥2) 时,5ᵏ 的末尾两位是 25。这意味着 5ᵏ 可以表示为
100 * m + 25
的形式(m 是某个整数)。 - 那么当 n=k+1 时,我们来计算 5ᵏ⁺¹: 5ᵏ⁺¹ = 5ᵏ * 5 = (100 * m + 25) * 5 = 500 * m + 125 = 5 * 100 * m + 100 + 25 = 100 * (5m + 1) + 25
- 你看,
100 * (5m + 1)
是 100 的倍数,所以100 * (5m + 1) + 25
这个数除以 100 的余数,依然是25
!
所以,根据数学归纳法,只要 n ≥ 2,5ⁿ 的末尾两位数就永远是 25。
题目给定的 n 的范围是 2 <= n <= 2*10^18
,完全符合我们 n >= 2
的条件。所以,那个超级大的 n 只是一个烟雾弹,用来吓唬人的,我们根本不需要对它做任何计算。无论 n 是多少,答案都是固定的 25
!
题解
所以,代码就变得超级简单啦,只需要读入一个我们根本用不上的 n,然后直接输出 25
就好啦。
#include <iostream>
int main() {
// 题目要求计算 5^n 的最后两位数,喵~
// 也就是计算 (5^n) % 100 的值。
// 我们来观察一下规律:
// 5^1 = 5
// 5^2 = 25
// 5^3 = 125
// 5^4 = 625
// ...
// 可以发现,只要 n >= 2,5^n 的最后两位总是 25。
// 题目给的 n 范围是 2 <= n <= 2*10^18,完全满足 n >= 2 的条件。
// 所以这个 n 具体是多少我们根本不用关心,它只是个烟雾弹!
// 我们只需要读取一下 n,然后直接输出固定的答案 "25" 就可以啦,喵~
long long n;
std::cin >> n; // 象征性地读一下输入
std::cout << 25 << std::endl; // 直接输出答案
return 0;
}
知识点介绍
这道题虽然简单,但是包含了一些在算法竞赛中非常有用的思想哦!
规律发现 (Pattern Recognition) 当遇到一个看似需要复杂计算,尤其是数据范围极大的题目时,不要急着去写复杂的算法。可以先从最简单的例子入手,手动计算几项,观察它们之间是否存在某种周期性或固定的规律。很多难题的突破口就在于发现这个隐藏的规律,就像这道题一样,喵~
模运算 (Modular Arithmetic) 求一个数的末尾 k 位,是一个非常经典的模运算应用。
- 求末尾一位,就是对
10
取模 (% 10
)。 - 求末尾两位,就是对
100
取模 (% 100
)。 - 求末尾 k 位,就是对
10^k
取模。 这个小技巧在处理大数问题时超级有用,一定要记住哦,主人!
- 求末尾一位,就是对
希望我的讲解对你有帮助哦!如果还有其他问题,随时可以再来找我,喵~ >w<