在这道题上浪费了很长时间。
自己写的很不好。时间和空间均超出限制,虽然最后的结果是正确的。
下面是自己的代码。
#include<stdio.h> #include<string.h> char n[10001][36000]; int max; void calculate(int i) { char temp[10]; memset(temp, 0, sizeof(temp)); int a = i, b = i + 1; int c = 0; while (b != 0) { temp[c++] = (b % 10) + '0'; b = b / 10; } b = i + 1; int la = strlen(n[a]); int lb = strlen(temp); int p, q, r; int bit = 0; char mul[36000]; for (p = 0; p < lb; p++) { memset(mul, 0, sizeof(mul)); r = p; bit = 0; for (q = 0; q < la; q++) { mul[r++] = (bit + (n[a][q] - '0')*(temp[p] - '0')) % 10 + '0'; bit = ((n[a][q] - '0')*(temp[p] - '0') + bit) / 10; } int s1; if (bit) { mul[r] = bit + '0'; s1 = r + 1; } else s1 = r; // add int s2 = strlen(n[b]); int s = s1 > s2 ? s1 : s2; bit = 0; for (q = 0; q < s; q++) { mul[q] = mul[q] == '\0' ? '0' : mul[q]; n[b][q] = n[b][q] == '\0' ? '0' : n[b][q]; int temp_bit = bit; bit = ((n[b][q] - '0') + (mul[q] - '0') + bit) / 10; n[b][q] = (((n[b][q] - '0') + (mul[q] - '0') + temp_bit) % 10) + '0'; } if (bit) n[b][q] = '1'; } } int main() { int m; int i; memset(n, 0, sizeof(n)); strncpy(n[0], "1", 1); strncpy(n[1], "1", 1); max = 1; while (EOF != scanf("%d", &m)) { if (max < m) { for (i = max; i <= m - 1; i++) calculate(i); max = m; } for (i = strlen(n[m]) - 1; i >= 0; i--) { if ('0' == n[m][i]) printf("0"); else printf("%c", n[m][i]); } printf("\n"); } return 0; }
鼓励一下自己:实实在在的努力,没有水分的成功,总是震撼人心的风景。
此处小结。
我以前做大数有关的题目时,都是把一个大数作为一个字符串处理,大数的一位数字是字符串的一个字符。
现在学会了新的方法。
万进制。用一个int作为万进制的一位。当然千进制等依此类推。
读了题解后,得到下面的方法。最后改来改去,自己的代码几乎和题解一样。当作模板用吧。
首先是10进制。时间卡的很紧。MAX设为40000超时,36000就通过了。
#include <stdio.h> #include <string.h> #define BASE 10 #define MAX 36000 int r[MAX]; int main() { int n; int i, j; int bit; while (EOF != scanf("%d", &n)) { memset(r, 0, sizeof(r)); r[0] = 1; for (i = 2; i <= n; i++) { bit = 0; for (j = 0; j < MAX; j++) { r[j] = r[j] * i + bit; bit = r[j] / BASE; r[j] = r[j] % BASE; } } for (i = MAX - 1; i >= 0; i--) { if (r[i]) break; } for (j = i; j >= 0; j--) printf("%d", r[j]); printf("\n"); } return 0; }
再尝试一下万进制。主要区别是BASE和MAX。
其中用到了printf("%04d"), 解释如下。
%nd 输出的整型宽度至少为n位,右对齐,%5d即宽度至少为5位,位数大于5则输出实际位数
%0nd 用得比较多,表示输出的整型宽度至少为n位,不足n位用0填充
printf("%05d",1)输出:00001
printf("%5d",1)输出:****1(*为空格)
附上代码。
#include <stdio.h> #include <string.h> #define BASE 10000 #define MAX 9000 int r[MAX]; int main() { int n; int i, j; int bit; while (EOF != scanf("%d", &n)) { memset(r, 0, sizeof(r)); r[0] = 1; for (i = 2; i <= n; i++) { bit = 0; for (j = 0; j < MAX; j++) { r[j] = r[j] * i + bit; bit = r[j] / BASE; r[j] = r[j] % BASE; } } for (i = MAX - 1; i >= 0; i--) { if (r[i]) break; } for (j = i; j >= 0; j--) { if(j == i) printf("%d", r[j]); else printf("%04d", r[j]); } printf("\n"); } return 0; }
时间大概是10进制的1/3到1/4。
先写到这里。
晚上回去的时候配置一下Java环境。尝试一下Java的大数类。