题目描述
Robb想知道阶乘n!第m位数码是什么?
输入
第一行是一个整数T,(1≤T≤10000)
每行一个样例,为2个整数n,m,0≤n≤1000,1≤m≤log10n!+1
输出
每行输出一个样例的结果
样例输入
3 5 1 5 2 5 3
样例输出
0 2 1
**解题思路:**一种简单的方法就是,用二维数组存下该阶乘的计算结果,一列存一位数,容易理解,但这样就需要耗费很大的空间。
例如num[0][1] = 1代表 0!第一位数是1,num[2][1] = 2 代表 2!第一位数是2 , num[4][1] = 4、num[4][2] = 2 代表 4! 第一位数是4、第二位数是2。。。。。
那么num数组 第一维开到 1000左右,没问题; 第二维: 1000! 看成 1000^1000, 那么 log10 1000^1000 = 1000* log10 1000 = 1000*3。 所以开到3000 肯定够了。
第二种方法就是,采用 万进制 思想,一个二维数组中,一列不再存1位数,而是4位数,甚至更多,这样就能很大的节省空间。减少循环量的同时,也是在减少计算量。
AC代码:(方法一)
cpp
#include <stdio.h>
int jinwei,weishu;
int num[1010][3000];
int main()
{
num[0][1] = 1; // 0的阶乘是1
num[1][1] = 1; // 1的阶乘是1
weishu = 1;
for ( int i = 2; i < 1001;i ++)
{
jinwei = 0;
for (int j = 1;j <= weishu && j < 3000; j ++)
{
num[i][j] = num[i-1][j] * i + jinwei; // 相乘 + 进位
jinwei = num[i][j] / 10; // 进位
num[i][j] %= 10;
if (jinwei != 0)
weishu ++;
}
}
int T,n,m;
scanf("%d",&T);
while ( T --)
{
scanf("%d %d",&n,&m);
printf("%d\n",num[n][m]);
}
return 0;
}