POJ 3331: Factorial Calculation (High Precision Problem)

  1. Overview:
    Give two numbers n, m, M is 0 to 9, ask n! How many m in the result;
    Input: (1) t: number of test cases; (2) n, m, total T lines;
    Output: n! Contains the number of M, a total of T lines.

  2. Solution:
    There are several procedures:

  3. Recursion is a common method to find factorial. Design a procedure, fac (n) = n × fac (n-1);
    The possible problem is that the result is too big for the computer to handle, for example, a 1000 bit number;

  4. Therefore, we must use high-precision algorithm to find the factorial of a number n by processing them in arrays;

  5. Judge the number of a number in each digit of a number;

  6. Multiplication by High Precision Calculation
    Simulate the process of vertical multiplication of a × B, a [0] is a bit, and the result of multiplication is put into sum. Vertical multiplication is: the number of a multiplied by the number of B, the number of a multiplied by the number of B I’ll make it up again.
    Note that a [i] × B [J] corresponds to the I + J bit of the product, that is sum [i + J], which means: in the vertical formula, the value of a bit multiplied by B bit (a [0] × B [0]) is in the s [0 + 0] of the result, the value of a bit multiplied by B bit (a [0] × B [1]) is in the s [0 + 1] of the result, and so on
    Because the value of the array is not limited, we should add up all the numbers that should be in a certain bit of the result (such as I + J bits), and then process the carry uniformly. Therefore, it is divided into two steps, first multiplying by bits and then accumulating, and then modulo 10 carry each bit of the result;

for(i=0;i<1001;i++)
{
for(j=0;j<1001;j++)
{
s[i+j]=s[i+j]+a[i]*b[j];
}
}
for(i=0;i<2000;i++)
{
s[i+1]=s[i+1]+s[i]/10;
s[i]=s[i]%10;
}

  1. Factorial by High Precision Calculation
    The simulation process is: for I, suppose that the result of (i-1)! Has been stored by bit in array a, then I! That is, I is multiplied by every bit in the a array starting from one bit. That is to say, starting from a [0], every bit of a in turn × I, after adding the carry (t records the carry, the initial value is 0), the remainder divided by 10 remains in this bit, and the quotient divided by 10 is used as the carry t to participate in the next calculation. The following is the core code for the problem:

int s=fac[j]*i+c;
fac[j]=s%10;
c=s/10;

  1. Code:

#include
#include
using namespace std;
int fac[10005];
int main()
{
int t,n,m,c,sum,i,j,k;
scanf("%d",&t);
while(t!=0)
{
scanf("%d%d",&n,&m);
t–;
for(i=0;i<1005;i++)
{
fac[i]=0;
}
fac[0]=1;
sum=0;
for(i=2;i<=n;i++)
{
c=0;
for(j=0;j<1000;j++)
{
int s=fac[j]*i+c;
fac[j]=s%10;
c=s/10;
//cout<<s<<" “;
//cout<<fac[j]<<” “;
//cout<<c<<” “;
}
//cout<<endl<<endl;
}
//cout<<endl;
for(k=1000-1;k>0;–k)
{
if(fac[k]) // Is 0, no number
break;
}
for(i=0;i<=k;i++) // From 0 to the bits with number, judge how many M are there
{
if(fac[i]==m)
sum++;
}
printf(”%d\n",sum);
}
system(“pause”);
return 0;
}

  1. Original Problem: http://poj.org/problem?id=3331
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值