这里本人采取递归与记忆化递归来解决此题,多说无益请看代码:

递归

#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;

}

总之递归跟记忆化递归逻辑差不多,一个注重结果,一个注重这个过程,但是记忆化搜索可以明显减少重复计算的次数。