import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
while(in.hasNextInt()){
BigInteger t=new BigInteger("1");
int n=in.nextInt();
for(int i=1;i<=n;i++){
BigInteger c=new BigInteger(String.valueOf(i));
t=t.multiply(c);
}
System.out.println(t);
}
in.close();
}}
这道题求阶乘,以为象前面做的那道一样简单,所以没有细想,提交了好多次,有个测试按例通不过,
后来发现是698阶乘的时候,我自己定义的long已经存不下了,这时候自然而然的想到了大数字处理类。
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void Add(){
Scanner input = new Scanner(System.in);
BigInteger a = input.nextBigInteger();
BigInteger b = input.nextBigInteger();
System.out.println(a.add(b));
}
public static void Factorial(){
Scanner input = new Scanner(System.in);
int n = input.nextInt(); //求n的阶乘
BigInteger answer = new BigInteger("1"); //结果初值为1
for(int i = 1; i<=n; i++){
//answer不能直接与i相乘
//大整数只能与大整数相乘
//调用valueOf方法把int型的i赋值给一个大整形数,然后再相乘
BigInteger current = BigInteger.valueOf(i);
answer = answer.multiply(current);
}
System.out.println(answer);
}
public static void main(String[] args) {
Factorial();
}
} import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
int n = scanner.nextInt();
BigInteger i = new BigInteger("1");
for (int j = 1; j <= n; j++) i=i.multiply(new BigInteger(String.valueOf(j)));
System.out.println(i);
}
}
} #include "stdio.h"
#define N 10000
int main(){
int res[1000]; //可以理解为res[1000]数组的每一个元素都记录N进制的1位
//其中N为10的乘方,这样,输出结果刚好可以用十进制表示
//由于N是10的乘方,该N进制的符号是十进制符号的组合,让我想到了等长码了都
//就好像时是16进制可以用4个二进制位表示一样,
//要注意保证res数组中所有元素都是4位,出了最高位的前缀0要去除
//越想越远了
int n,i,j,bit,carry;//bit表示当前运算结果的最高位,也就是res数组的不为0的最大下标
//carry表示进位的结果
while(~scanf("%d",&n)){
res[bit=0] = 1;//一开始res数组应该表示1,阶乘,初始值存1,
//加法初始值存0,其中只需要初始化数组的第一个元素就行了
for(i = 1; i <= n; i++){
carry = 0;
for(j = 0; j <= bit; j++){
res[j] = res[j]*i + carry;//每一位的结果是当前位乘以乘数在加上进位的结果
//第一位运算时进位为0,需要将carry提前初始化为0
carry = res[j] / N;//将当前位的运算结果分解为当前位和高一位存入当前位和carry
res[j] = res[j] % N;
}
//依次从当前位到最高位计算,最高位可能产生进位
if(carry) res[++bit] = carry;
}
//高位补0用的格式字符串%04d,我看大佬都是用%4.4ld,
//不知道为毛,网上也没查出一个好的解释来
for(printf("%d",res[bit]);bit;printf("%04d",res[--bit]));
printf("\n");
}
return 0;
}
#include<stdio.h>
int s[1000]={1},n=1000000,t=2,a=0,b=0,m=0,p;
int main()
{
int N;
while(~scanf("%d",&N))
{
for(;a<=m||++t<=N&&(a=b=0,1);m==a++&&b&&m++)
s[a]=(b+=s[a]*t)%n,b/=n;
for(printf("%d",s[p=m]);m--;printf("%06d",s[m]));
for(printf("\n");p;s[p--]=0);
s[0]=1,a=b=m=0,t=2;
}
} #include <iostream>
#include <string.h>
using namespace std;
int main(){
int N;
int s[10000]={0},i;//用于保存超过int范围的超大数字,按照从个位往上进位的方式更新数据
//核心思路:乘法转换成加法
//怎么确定完整数字的终点:最高位数字与i的乘积+前一位进位是否产生进位
while(cin>>N){
memset(s,-1,sizeof(s));//
s[0]=1;//将个位设为1
int i,j,temp,k,index;//k记录进位
for(i=1;i<=N;++i){//本轮阶乘的数字
k=0;//进位设置为零
//遍历结果数组中的每个个位整数
for(j=0;s[j]!=-1;++j){//-1标识最高位结束
temp=s[j]*i+k;
s[j]=temp%10;
k=temp/10;//下一个数的进位
}
//***********确定完整数字的终点,或者总共数组长度的方法:
//当i乘以当前数组的最高位时,若存在进位则根据当前数组长度递增
while(k){
s[j]=k%10;
++j;
k/=10;
}
index=j-1;
}
//逆序输出数组中的数字
for(i=index;i>=0;--i)
cout<<s[i];
cout<<endl;
}
}
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
while(in.hasNextInt()){
int N = in.nextInt();
BigInteger sum = BigInteger.valueOf(1);
for(int i=1;i<=N;i++)
sum = sum.multiply(BigInteger.valueOf(i));
System.out.println(sum);
}
}
}
java也有春天
package com.speical.improve;
import java.util.Scanner;
/**
* 大数的阶乘
* @author special
* @date 2017年12月23日 下午4:36:47
*/
public class Pro23Improve1 {
private static String[] factories = new String[1000 + 5];
static{
factories[0] = "1";
factories[1] = "1";
}
/**
* 两字符串相乘
* @param str1
* @param str2
* @return
*/
public static String mutiple(String str1, String str2){
int length1 = str1.length();
int length2 = str2.length();
int totalLength = length1 + length2;
char[] result = new char[totalLength]; //两数相乘最大位数为 两数位数之和
for(int i = 0; i < totalLength; i++) result[i] = '0'; //注意初始化为'0'
int carry = 0;
for(int j = length2 - 1; j >= 0; j--){
carry = 0;
for(int i = length1 - 1; i >= 0; i--){
int temp = (str1.charAt(i) - '0') * (str2.charAt(j) - '0')
+ (result[i + j + 1] - '0') + carry;
if(temp >= 10){
carry = temp / 10; //注意此处的顺序,坑死我了
temp %= 10;
}else {
carry = 0;
}
result[i + j + 1] = (char) (temp + '0'); // i + j + 1正好第j轮相乘,个位应该放的位置
}
if(carry > 0) result[j] = (char) (carry + '0'); // j 正好是第j轮相乘的应该进位的位置
}
return new String(result).substring(result[0] != '0' ? 0 : 1);
}
public static String getFactories(int n){
String res = "1";
for(int i = n; i >= 2; i--){
if(factories[i] != null){
res = mutiple(res,factories[i]);
break;
}
else
res = mutiple(res, String.valueOf(i));
}
factories[n] = res;
return res;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
while(input.hasNext()){
int n = input.nextInt();
System.out.println(getFactories(n));
}
}
}
import java.math.BigInteger;
import java.util.Scanner;
public class Seven {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()){
int number = sc.nextInt();
System.out.println(jieCheng(number));
}
}
public static BigInteger jieCheng(int number){
if (number==1){
return BigInteger.valueOf(1);
}else
return jieCheng(number-1).multiply(BigInteger.valueOf(number));
}
}
#include<bits/stdc++.h>
int main(){
int n;
while(scanf("%d",&n)!=EOF){
long long a[301]={1};
for(int i=2;i<=n;i++){
long long s=0,t;
for(int j=0;j<=300;j++){
t=a[j]*i+s;a[j]=t%1000000000;
s=t/1000000000;
}
}//每个数组单元存放9位十进制数字,中间数组单元0的个数会被压缩
int i;
for(i=300;a[i]==0;i--);
printf("%lld",a[i]);
for(int j=i-1;j>=0;j--)
printf("%09lld",a[j]);//对中间数组单元的0解压缩
printf("\n");
}
}
#include<stdio.h>
#define width 3000
int main()
{
int i,j;
int k,r,t;
int N;
int d[width];
while(scanf("%d",&N)!=EOF)
{
t=0;
for(i=0;i<width;i++) /**给数组初始化为零*/
d[i]=0;
d[0]=1; /**个位初始化为1*/
for(i=1;i<=N;i++) /**从1到N进行阶乘*/
{
k=0;
for(j=0;j<=t;j++)/**从个位开始往高位运算*/
{
r=(d[j]*i+k)/10; /**第j位乘以i加上后一位运算得到的k,在除以10得到k*/
d[j]=(d[j]*i+k)%10;/**第j位乘以i加上后一位运算得到的k,再取余得到运算后第j位的只*/
k=r;
}
while(k!=0) /**k!=0说明要向高位进位*/
{
d[++t]=k%10;
k=k/10;
}
}
for(i=t;i>=0;i--) /**从个位开始输出各位数字*/
printf("%d",d[i]);
printf("\n");
}
return 0;
}
#include <stdio.h>
long res[10000];
int factorial(const int n){
int i,j,carry,bit;
for(res[bit=carry=0]=i=1;i<=n;++i,carry=0){
for(j=0;j<=bit;++j){
res[j]=res[j]*i+carry;
carry=res[j]/10000;
res[j]%=10000;
}
if (carry) res[++bit]=carry;
}
for(printf("%ld",res[i=bit]);i;printf("%4.4ld",res[--i]));
return printf("\n");
}
int main(){
for(int n;~scanf("%d",&n);factorial(n));
return 0;
}
#include <iostream>
#define width 3000 //利用数组存储大数,1000!大约是两千多位,使用3000位够了
using namespace std;
int main()
{
int N,i,num[width]={0}; //初始化
while(cin >> N)
{
num[0]=1; //个位为1
int nowWid=1,j,carry,tmp; //nowWid代表当前大数数组位数
for(i=2;i<=N;i++) //从2开始
{
carry=0; //进位初始化为0
for(j=0;j<nowWid;j++)
{
tmp=(num[j]*i+carry)/10; //tmp暂时存储进位值
num[j]=(num[j]*i+carry)%10;
carry=tmp;
}
while(carry != 0) //进位
{
num[nowWid++]=carry%10;
carry /= 10;
}
}
while(nowWid--)
cout << num[nowWid];
cout << endl;
}
return 0;
}
老方法,转化为字符串
#include <bits/stdc++.h>
using namespace std;
string Multiple(string str,int n)
{
long long carry=0;
for(int i=str.size()-1;i>=0;i--)
{
long long current=carry+(str[i]-'0')*n;
str[i]=current%10+'0';
carry=current/10;
}
if(carry!=0)
{
str=to_string(carry)+str;
}
return str;
}
int main()
{
int n;
while(cin>>n)
{
string answer="1";
for(int i=1;i<=n;i++)
{
answer=Multiple(answer,i);
}
cout<<answer<<endl;
}
return 0;
} #include<stdio.h>
int digit[1000], n;
int main() {
while (~scanf("%d", &n)) {
int cnt = 0, carry = 0, i, tmp;
for (digit[0] = 1, i = 1; i <= n; i++, carry = 0) {
for (int j = 0; j <= cnt; digit[j++] = tmp) {
tmp = (digit[j] * i + carry) % 10000;
carry = (digit[j] * i + carry) / 10000;
}
if(carry) digit[++cnt] = carry;
}
for (printf("%d", digit[i = cnt]),--i; i >= 0; printf("%04d",digit[i--]));
printf("\n");
}
return 0;
}