#include<bits/stdc++.h> using namespace std; const int maxn = 1e2; int ans[maxn/2]; int len; void getFact(int n) { for(int x = 2;x <= n; x++) { int c = 0; for(int i = 0;i < len; i++) { int t = ans[i]*x+c; ans[i] = t%10; c = t/10; } while(c) { ans[len++] = c%10; c /= 10; } } } int main() { ios::sync_with_stdio(false); int n; while(cin >> n) { fill(ans, ans+maxn/2, 0); len = 0; ans[len++] = 1; getFact(n); for(int i = len-1;i >= 0; i--) cout << ans[i]; cout << "\n"; } return 0; }
#include <stdio.h> long long int count(long long int x); int main(void) { long long int n; while (scanf("%lld", &n) != EOF && (n >= 1 && n <= 20)) { printf("%lld\n", count(n)); } return 0; } long long int count(long long int x) { if (1LL == x) { return 1LL; } else { return x * count(x - 1); } }//最保险的做法就是直接设为long long int进行递归,递归时最多压栈20层不会栈溢出;
#include<iostream> using namespace std; long long int factorial(int n){ if(n==1){ return 1; } else{ return n*factorial(n-1); } } int main(){ int n; while(cin>>n){ cout<<factorial(n)<<endl; } return 0; }
#include <stdio.h> #define MAXSIZE 40000 void multiple(int *a,int m) { int c=0; for(int i=MAXSIZE-1; i>=0; i--) { int t=a[i]*m+c; a[i]=t%10; c=t/10; } } int main() { int n; while(scanf("%d",&n)!=EOF) { int a[MAXSIZE]= {0}; a[MAXSIZE-1]=n; for(int i=n-1; i>1; i--) { multiple(a,i); } int flag=0; for(int i=0; i<MAXSIZE; i++) { if(a[i]!=0) { flag=1; } if(flag==1) { printf("%d",a[i]); } } printf("\n"); } return 0; }
#include <stdio.h> int main() { int n; while (scanf("%d",&n)!=EOF) { int a[10000]={1}; int p=0,c; //进位为c,用p指示当前结果位数 for(int i=1;i<=n;i++) { c=0; for(int j=0;j<=p;j++) { a[j]=a[j]*i+c; //a[j]此时实际的数值(乘积加上进位) c=a[j]/10000; //下一位(a[j+1])的进位 a[j]=a[j]%10000; //a[j]要显示出的数值 } while(c!=0) //若最终进位不为0,说明p+1上也有数值 { a[++p]=c%10000; c/=10000; } } printf("%d",a[p]); //第一位不需要输出前导0 for(int i=p-1;i>=0;i--)printf("%04d",a[i]); //逆序输出,注意前导0 printf("\n"); } }
大数运算,存储一个大数的数组为1000大小时最大可以计算449的阶乘。代码丑陋。
#include<string>
using namespace std;
struct bign{
int len;
int d[1000];
bign(){
len = 0;
fill(d, d + 1000, 0);
}
};
bign multi(bign a, int b){
bign c;
int carry = 0;
for(int i = 0; i < a.len; i++){
int temp = a.d[i] * b + carry;
c.d[c.len++] = temp % 10;
carry = temp / 10;
}
while(carry != 0){
c.d[c.len++] = carry % 10;
carry /= 10;
}
return c;
}
void factorial(int n){
bign ret;
ret.len = 1;
ret.d[0] = 1;
for(int i = 2; i <= n; i++){
ret = multi(ret, i);
}
cout << ret.len << endl;
for(int i = ret.len - 1; i >= 0; i--){
cout << ret.d[i];
}
cout << endl;
}
int main(){
int n;
while(cin >> n){
bign ret;
factorial(n);
}
return 0;
}
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
long result=1;
for(int i=1;i<=n;i++){
result*=i;
}
cout<<result<<endl;
} //感觉这个主要涉及的问题就是结果的存储类型吧,用long,由于限制了n的范围,所以还不需要用到大数乘法
#include<stdio.h> #define MAX 300 void fact(int n); int main() { int number; int p = scanf("%d",&number); while(p != EOF) { fact(number); printf("\n"); p = scanf("%d",&number); } return 0; } void fact(int n) { int a[MAX]={1}; int digit=1; /*阶乘至少为1位,因此digit(位数)初始值为1*/ int carry=0; /*进位*/ int temp,i,j; for (i=1;i<=n;i++) { for (j=0;j<digit;j++) { temp=a[j]*i+carry; /*temt为未进位前的数字*/ a[j]=temp%10; carry=temp/10; } while(carry!=0) { a[++digit-1]=carry%10; /*必须限制carry在[0,9]*/ carry=carry/10; } } for(i=digit-1;i>=0;i--) { printf("%d",a[i]); } }感觉好坑爹啊,原来这个OJ要一直输入测试用例!
大数阶乘问题,但是题目做了简化,限制n(1<=n<=20),所以普通解法就能通过。 但是,如果不对n做限制呢?那就是典型的大数问题了,字符串是解决大数问题的有效手段, 可能不是最简单的,但是是万能的。对这个题来说,只要实现了字符串的乘法,不管多大的 n,都能实现阶乘的运算。例如a = "123",b = "56",a * b = "123" * "6" + "123" * "50",而"123" * "50" = "123" * "5" + "0". 这样就得到了两个大数相乘的结果。因 此,要实现字符串相乘运算,首先要实现字符串和单个字符的相乘运算(其实是为了简 化多位数乘法),然后要实现字符串的相加运算。这个思路实现如下: #include <iostream> #include <string> using namespace std; string add(const string a, const string b){ string res; int i = a.size() - 1; int j = b.size() - 1; int extra = 0; while (i >= 0 && j >= 0){ res = to_string((a[i] - '0' + b[j] - '0' + extra) % 10) + res; extra = (a[i] - '0' + b[j] - '0' + extra) / 10; i--; j--; } while (i >= 0){ res = to_string((a[i] - '0' + extra) % 10) + res; extra = (a[i] - '0' + extra) / 10; i--; } while (j >= 0){ res = to_string((b[j] - '0' + extra) % 10) + res; extra = (b[j] - '0' + extra) / 10; j--; } if (extra != 0) res = to_string(extra) + res; return res; } string _mul(const string a, const char b){ string res; int extra = 0; int i = a.size() - 1; while (i >= 0){ res = to_string(((a[i] - '0') * (b - '0') + extra) % 10) + res; extra = ((a[i] - '0') * (b - '0') + extra) / 10; i--; } if (extra != 0) res = to_string(extra) + res; return res; } string multiply(const string a, const string b){ string res; for (int i = b.size() - 1; i >= 0; i--){ string temp = _mul(a, b[i]); for (int j = 0; j < (int)b.length() - 1 - i; j++) temp = temp + "0"; res = add(res, temp); } return res; } string factorial(int n){ string res = "1"; for (int i = 2; i <= n;i++){ res = multiply(res, to_string(i)); } return res; } int main(){ int n; while (cin >> n){ string res = factorial(n); cout << res << endl; } return 0; }