这里本人采取递归与记忆化递归来解决此题,多说无益请看代码:
递归
#include<bits/stdc++.h>
using namespace std;
long long solve(int n) {
if (n == 0 || n == 1) return 1;
long long res = n * solve(n - 1);
// 去掉末尾的0
while (res % 10 == 0) {
res /= 10;
}
// 保留最后10位非零数字(避免溢出且保留足够信息)
res %= 10000000000;//这里本人也是被绊了一跤
return res;
}
int main() {
int n;
cin >> n;
long long ans = solve(n);
// 输出结果的最后一位
cout << ans % 10 << endl;
return 0;
}
记忆化递归
#include<bits/stdc++.h>
using namespace std;
const int Max=10000000;
long long a[Max] = {0}; // 记忆化数组,存储n!的最后非零数字的中间结果
long long solve(int n) {
if (n == 0 || n == 1) return a[n] = 1;
if (a[n] != 0) return a[n]; // 已计算过,直接返回
long long res = n * solve(n - 1);
// 去除末尾0
while (res % 10 == 0) {
res /= 10;
}
// 保留足够位数(避免溢出和信息丢失)
res %= 10000000000; // 保留最后10位
return a[n] = res;
}
int main() {
int n;
cin >> n;
solve(n);
cout << a[n] % 10 << endl; // 输出最后一位非零数字
return 0;
}
总之递归跟记忆化递归逻辑差不多,一个注重结果,一个注重这个过程,但是记忆化搜索可以明显减少重复计算的次数。

京公网安备 11010502036488号