蓝桥杯练习——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的求法可以用下面这个简洁有力的代码
int func2(int a){ if(a%10!=0) return a%10; else func2(a/10); }