洛谷 P1134 階乘問題
阿新 • • 發佈:2018-12-11
一開始只保留最後一位,交上去29
#include<cstdio> #include<cmath> #include<algorithm> #define REP(i, a, b) for(int i = (a); i < (b); i++) #define _for(i, a, b) for(int i = (a); i <= (b); i++) using namespace std; int main() { int n, ans = 1; scanf("%d", &n); _for(i, 2, n) { ans *= i; while(ans % 10== 0) ans /= 10; ans %= 10; } printf("%d\n", ans % 10); return 0; }
然後通過資料發現
然後我就把真正的數和我保留最後一位的數比較一下,發現有一組資料答案有問題
i = 14 sum = 87178291200 ans = 2
i = 15 sum = 130767436800 ans = 3
這組資料是關鍵 如果按照最後一位的話,2 * 15 = 30, 取3 但是我們把sum手算乘上15會發現 87178291200 15 ---------------- …… 60 ……2 ----------------- ……80 這裡可以看到,影響到末尾的位的是後兩位,而不僅僅是最後一位 所以以此類推,乘數最大為10的8次方方級別,所以我就只需要存 去0情況下的最後8位數就好了。8位數乘8位數int會炸,所以開longlong
#include<cstdio> #include<cmath> #include<algorithm> #define REP(i, a, b) for(int i = (a); i < (b); i++) #define _for(i, a, b) for(int i = (a); i <= (b); i++) using namespace std; typedef long long ll; const int base = 1e8; int main() { int n; ll ans = 1; scanf("%d", &n); _for(i, 2, n) { ans *= i; while(ans % 10== 0) ans /= 10; ans %= base; } printf("%lld\n", ans % 10); return 0; }