LightOj 1090 - Trailing Zeroes (II)---求末尾0的个数
题目链接:http://lightoj.com/volume_showproblem.php?problem=1090
题意:给你四个数 n, r, p, q 求C(n, r) * p^q的结果中末尾0的个数;(1<=n, r, p, q <= 10^6, r ≤ n)
要求末尾0的个数,一定和2和5有关,例如num1 * num2结果中末尾0的个数可以表示成min(num1中2的个数+num2中2的个数, num1中5的个数+num2中5的个数);
对于C(n, r)中0的2的个数可以写成f[n]-f[r]-f[n-r],其中f[i]表示i!中2的个数;打表求出 f 即可
#include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> typedef long long LL; #define N 1000001 using namespace std; const double eps = 1e-6; int f[N], g[N]; ///f[i]表示i!中共有多少个2, g[i]表示i!有多少个5; void Init() { int x = 0, y = 0; for(int i=1; i<N; i++) { int n = i; while(n%2 == 0) { x ++; n /= 2; } n = i; while(n%5 == 0) { y ++; n /= 5; } f[i] = x; g[i] = y; } } int main() { Init(); int T, t = 1; scanf("%d", &T); while(T --) { int p, q, n, r; scanf("%d %d %d %d", &n, &r, &p, &q); int ans1, ans2, ans; ans1 = f[n]-f[r]-f[n-r] + q*(f[p]-f[p-1]); ans2 = g[n]-g[r]-g[n-r] + q*(g[p]-g[p-1]); ans = min(ans1, ans2); printf("Case %d: %d\n", t++, ans); } return 0; }