1 条题解
-
1
题目分析
题意简述
本题通过预先计算并存储一系列数值到二维数组
res
中,然后根据输入的整数 ,输出数组res
中对应 的数值。当输入的 为 时,程序结束。输出格式为 “N=n: 数值”,其中数值由数组res
中 对应的最高位以及其他位组成,其他位以四位一组的形式输出,不足四位的前面补 。输入
- 多组测试用例,每组为一个整数 。
- 当输入的整数 为 时,程序终止。
输出
对于每组输入(除 外),输出格式为 “N=n: 数值”,数值由数组
res
中 对应的最高位以及其他位组成,其他位以四位一组的形式输出,不足四位的前面补 。
解题思路
数组初始化
定义二维数组
res[MAXN][MAXM]
用于存储计算结果,数组msb[MAXN]
用于记录res[i][]
中最高位的位置。初始化res[3][0] = 4
和msb[3] = 0
,表示预先设定的初始状态。递推计算
通过循环
for (i = 3; i < MAXN - 2; ++i)
进行递推计算:- 内层循环
for (j = 0; j <= msb[i]; ++j)
对res[i][]
中的每一位进行处理,将res[i][j]
乘以 后累加到res[i + 1][j]
中,同时处理进位,将res[i + 1][j]
除以BASE
的结果累加到res[i + 1][j + 1]
中,res[i + 1][j]
取模BASE
。 - 根据
res[i + 1][msb[i] + 1]
是否为 来更新msb[i + 1]
的值,如果res[i + 1][msb[i] + 1]
不为 ,则msb[i + 1] = msb[i] + 1
,否则msb[i + 1] = msb[i]
。
输入处理与结果输出
使用
while (scanf("%d", &n) != EOF && n != -1)
循环读取输入的整数 ,当 为 时结束循环。对于每个输入的 ,先输出 “N=n:”,然后输出res[n][msb[n]]
作为最高位,再通过循环for (i = msb[n] - 1; i >= 0; --i)
以四位一组的形式输出res[n][i]
,不足四位的前面补 。
代码实现
#include <stdio.h> #define MAXN 205 #define MAXM 1050 #define BASE 10000 int res[MAXN][MAXM] = {0}, msb[MAXN] = {0}; //2*(i-1)!保存在res[i][]中,msb[i]为2*(i-1)!最高位的位置 int main() { int n, i, j; res[3][0] = 4; msb[3] = 0; for (i = 3; i < MAXN - 2; ++i) { for (j = 0; j <= msb[i]; ++j) { res[i + 1][j] += res[i][j] * i; res[i + 1][j + 1] += res[i + 1][j] / BASE; res[i + 1][j] %= BASE; } if (res[i + 1][msb[i] + 1]) msb[i + 1] = msb[i] + 1; else msb[i + 1] = msb[i]; } while (scanf("%d", &n) != EOF && n != -1) { printf("N=%d:\n%d", n, res[n][msb[n]]); for (i = msb[n] - 1; i >= 0; --i) printf("%04d", res[n][i]); printf("\n"); } return 0; }
代码说明
- 宏定义:使用
#define
定义了三个宏MAXN
、MAXM
和BASE
,分别表示数组的大小和进制基数。 - 数组定义:定义了二维数组
res
和一维数组msb
,并对其进行了注释说明。 - 初始化:对
res[3][0]
和msb[3]
进行初始化。 - 递推计算循环:外层循环控制计算的轮数,内层循环处理每一位的计算和进位。
- 最高位位置更新:根据
res[i + 1][msb[i] + 1]
的值更新msb[i + 1]
。 - 输入处理与输出循环:通过
while
循环读取输入的整数 ,根据 输出相应的结果,输出时按照特定格式进行。
- 1
信息
- ID
- 355
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者