USACO Factorials,DP,因子分解

来源:互联网 发布:电工理论与新技术 知乎 编辑:程序博客网 时间:2024/05/16 15:35

思路:先计算 n! 中有多少个 5 因子,并记录下来。然后从 1 到 n 把每个因数列出来,如果能去掉 2 和 5 (数量都是因子 5 的个数),就把 2 和 5 去掉。这样中间计算的数只用保留 1 位(mod 10) 就可以了。
官方给的分析:

The insight for this problem is that 0's at the end of a number come from it being divisible by 10, or equivalently, by 2 and 5. Furthermore, there are always more 2s than 5s in a factorial.

To get the last digit of the factorial, we can run a loop to calculate it modulo 10, as long as we don't include any 2s or 5s in the product. Of course, we want to exclude the same number of 2s and 5s, so that all we're really doing is ignoring 10s. So after the loop, we need to multiply in any extra 2s that didn't have 5s to cancel them out.



/* ID: wangxin12 PROG: fact4LANG: C++ */ #include <iostream>#include <fstream>using namespace std;int N; // 1 <= N <= 4220int n[4221];int ans[4221]; int main() {ifstream fin("fact4.in");ofstream fout("fact4.out");int i,j;ans[0] = 1;fin>>N;for(i = 0; i <= N; i++)n[i] = i;int counter = 0;for(i = 1; i <= N; i++) {while((n[i] % 5 == 0) && n[i] > 0) {n[i] /= 5;counter++;}}for(i = 1; i <= N; i++) {while(n[i] % 2 == 0 && n[i] > 0 && counter > 0) {n[i] /= 2;counter--;}}for(i = 1; i <= N; i++) {int temp = ans[i - 1] * n[i];ans[i] = temp % 10;}fout<<ans[N]<<endl;fin.close();fout.close();return 0;}



描述

N的阶乘写作N!,表示小于等于N的所有正整数的乘积。 阶乘会变大得很快,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了。 你的任务是找到阶乘最后面的非零位。举个例子:

5!=1*2*3*4*5=120,所以5!的最后面的非零位是2。7!=1*2*3*4*5*6*7=5040,所以最后面的非零位是4。

[编辑]格式

PROGRAM NAME: fact4

INPUT FORMAT:

(fact4.in)

共一行,一个不大于4,220的正整数N

OUTPUT FORMAT:

(fact4.out)

共一行,输出N!最后面的非零位。

[编辑]SAMPLE INPUT

7

[编辑]SAMPLE OUTPUT

4

原创粉丝点击