题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1042
题目很简单,就是求N!=N×(N-1)×...×1,但是这里不能用递归,因为N≤10000,一般的内部基本数据无法满足要求。所以考虑采用一个数组来模拟之,起初考虑的是让数组每一位代表0~9中的一个数,程序源代码为:
1 /**
2 * a[MAX_N]的任一个元素存储0~9中的某一个数字
3 */
4 #include <iostream>
5 #include <cstdio>
6 #include <cstring>
7 using namespace std;
8 #define MAX_N 50000
9 int main()
10 {
11 int N, a[MAX_N], i, j, R, P;
12 while(scanf("%d", &N) != EOF)
13 {
14 memset(a, 0, sizeof(a));
15 a[0] = 1;
16 for(i = 1; i <= N; i++)
17 {
18 R = 0;
19 for(j = 0; j < MAX_N; j++)
20 {
21 P = a[j]*i+R;
22 a[j] = P%10;
23 R = P/10;
24 }
25 }
26
27 for(i = MAX_N-1; i >= 0; i--)
28 if(a[i] != 0) break;
29 for(j = i; j >= 0; j--)
30 printf("%d", a[j]);
31 printf("\n");
32 }
33 return 0;
34 }
提交后,时间很大,差点TLE,为
5058183 | 2011-11-26 12:33:25 | Accepted | 1042 | 4640MS | 452K | 661 B | G++ | XXX |
后来参考网上一些说法,采用四位一进位的方法,效率大大提高,代码和刚才基本一样:
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 using namespace std;
5 #define MAX_N 10000
6 int main()
7 {
8 int a[MAX_N], N, P, R, Ij, i, j;
9 while(scanf("%d", &N) != EOF)
10 {
11 memset(a, 0, sizeof(a));
12 a[0] = 1;
13 for(i = 2; i <= N; i++)
14 {
15 for(j = MAX_N-1; j >= 0; j--)
16 if(a[j] != 0) break;
17 R = 0; Ij = ++j;
18 for(j = 0; j <= Ij; j++)
19 {
20 P = a[j]*i+R;
21 a[j] = P%10000;
22 R = P/10000;
23 }
24 }
25
26 for(i = MAX_N-1; i >= 0; i--)
27 if(a[i] != 0) break;
28 printf("%d", a[i]);
29 for(j = i-1; j >= 0; j--)
30 printf("%04d", a[j]);
31 printf("\n");
32 }
33 return 0;
34 }
运行时间仅为343MS,不过也见到比这个代码运行时间更小的,我不知道怎么修改...
5058422 | 2011-11-26 13:15:41 | Accepted | 1042 | 343MS | 300K | 803 B | G++ | XXX |