蓝桥杯练习——C++输出阶乘的最右边一位非零数

 1 #include<iostream>
 2 #include<iomanip>
 3 using namespace std;
 4 #define M 10000 
 5 #define N 10000 
 6 int p=1; 
 7 int func2(int a);
 8 void func(int *a,int n) 
 9 { 
10 int i,j,k; 
11 for(j=2;j<=n;j++) 
12 { 
13 k=0; 
14 for(i=0;i<p;i++) 
15 a[i]*=j; 
16 for(i=0;i<p;i++) 
17 { 
18 a[i]+=k; 
19 k=a[i]/M; 
20 a[i]%=M; 
21 } 
22 if(k) 
23 { 
24 p++; 
25 a[p-1]+=k; 
26 } 
27 } 
28 //cout<<a[p-1];
29 int tempnum=0;
30 for(int i=0;i<p-1;i++)
31 {
32     if(a[i]!=0)
33     {
34     
35     cout<<a[i]<<endl;
36     tempnum=a[i];
37    cout<<    func2(tempnum)<<endl;
38     break;
39 }
40 }
41 } 
42 
43 int func2(int a){    //取非零数
44         if(a%10!=0)
45         return a%10;
46         else
47         func2(a/10);
48     
49 
50 }
51 int main() 
52 { 
53 int a[N]={0},n,i; 
54 while(cin>>n) 
55 { 
56 for(i=0;i<N;i++) 
57 a[i]=0; 
58 a[0]=1;p=1; 
59 func(a,n); 
60 } 
61 return 0; 
62 }

初学C++时我们求阶乘用的是经典的递归方法,非常简单。但是假如我们要求一个稍微大一点的数,例如13的阶乘,这时候问题就来了。

我们知道unsigned int   的范围是0~4 294 967 295 ,而13的阶乘6 227 020 800 已经超出了int的范围。即使是unsigned long long 的取值范围也才

0~18 446 744 073 709 551 615,而22!的值已经是1.1240007277776 * 10 21

求大数阶乘的程序网上有很多,多是模拟手工计算的方法(创建一个数组,数组中数据超过10000时进位),我们的问题是如何取到阶乘的最右边一位非零数。

这里包含两个需要计算的数据

  1. 所求阶乘的最后一组数据。
  2. 取到非零位

1的求法我们可以用大数阶乘的程序,只要在输出时只输出最右边非零的那个数组就可以了。

2的求法可以用下面这个简洁有力的代码

int func2(int a){
        if(a%10!=0)
        return a%10;
        else
        func2(a/10);
}

 

posted @ 2015-06-12 22:23  六层楼  阅读(2088)  评论(0编辑  收藏  举报