冲着51nod新UI去做了题,顺便总结一下,这里有2道阶乘的题,
n的阶乘后面有多少个0?
6的阶乘 = 1*2*3*4*5*6 = 720,720后面有1个0。
Input
一个数N(1 <= N <= 10^9)
OutPut
输出0的数量
Input示例
5
Output示例
1
好吧,确实,问题就是,末尾的0是怎么构成的,仔细想一下,还是能想出来,是5和其他偶数相乘得到的,这样下去,是不是只要因子5的个数就好了?确实,因为从1~N的阶乘中,凡是遇到5的倍数的,之前都有偶数,如下:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 .....5n-1, 5n....N
5之前有偶数2和4,10之前有偶数6和8,这样,每个5n之前都有偶数能够跟它构成阶乘末尾的一个0,把这些5n抽出来,可以得到 5^k * k! (k = N/5) ,这样,可以先得到k个5,然后再递归求k!中5的个数,就可以求出因子5的个数了,好了,上代码:
#include <iostream> using namespace std; int main(){ int a, ans = 0; cin >> a; while(a){ a /= 5; ans += a; } cout << ans; return 0; }之前写了个递归,过不了。,。。这样就能AC了。
输入N和P(P为质数),求N! Mod P = ? (Mod 就是求模 %)
例如:n = 10, P = 11,10! = 3628800
3628800 % 11 = 10
Input
两个数N,P,中间用空格隔开。(N < 10000, P < 10^9)
OutPut
输出N! mod P的结果。
Input示例
10 11
Output示例
10
一看到这题,就在想阶乘能否算出来,要是N等于9999的话,N!是非常大的,会溢出,用大数来模拟也很麻烦,醉了,好吧,上网搜了一下,取模运算是有规律的,其中,有一条规律是这样的,
(a * b) % p = (a % p * b % p) % p
我想,这规律怎么小学的时候没看到。。。
好吧,通过这个规律,可以推出:
N! % P = ((N-1)! % P) * N % P
也就是说,在求N-1的阶乘的时候,可以求模,然后保存余数,下一轮就可以用余数来乘以N,然后求模,就求出N的阶乘模P的结果了,代码如下:
#include <iostream> using namespace std; int main(){ long long N, P, ans = 1; cin >> N >> P; for(long long i = 2; i <= N; i++){ ans = (ans * i) % P; if(ans == 0) break; } cout << ans; return 0; }这里如果用int的话,是不能通过的。
版权声明:本文为博主原创文章,未经博主允许不得转载。