冲着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的话,是不能通过的。




版权声明:本文为博主原创文章,未经博主允许不得转载。

 posted on 2015-01-18 00:51  Rex7  阅读(426)  评论(0编辑  收藏  举报