首页 > 试题广场 >

N的阶乘

[编程题]N的阶乘
  • 热度指数:23278 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
 输入一个正整数N,输出N的阶乘。

输入描述:
正整数N(0<=N<=1000)


输出描述:
 输入可能包括多组数据,对于每一组输入数据,输出N的阶乘
示例1

输入

4
5
15

输出

24
120
1307674368000
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已经存不下了,这时候自然而然的想到了大数字处理类。


发表于 2016-04-29 18:46:21 回复(1)
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();

    }
}

发表于 2021-03-06 11:12:06 回复(0)
/*
*直接上高精度阶乘。
*/


#include<bits/stdc++.h>
using namespace std;

vector<int> v;

void multi(int x)        //先各个位乘   再处理进位
{
    for(int i = 0;i < v.size(); i++)
       v[i] = v[i] * x;                  
}

void Jin()    //处理进位
{
    int c = 0;
    for(int i = 0;i < v.size(); i++)
    {
        int t = v[i];
        v[i] = (t+c)%10; c = (t+c)/10;
    }
    if(c) v.push_back(c);
    while(v[v.size()-1] >= 10)     //一定要注意    这里最高位可能还>=10  要继续向前进
    {
        int t = v[v.size()-1];
        v[v.size()-1] = t%10; v.push_back(t/10);
    }
}

int main()
{
    int n;
    while(cin >> n)            //实现n!
    {
        v.clear(); v.push_back(1);
        for(int i = 2;i <= n; i++)
        {
            multi(i); Jin();
        }
        for(int i = v.size()-1;i >= 0; i--) cout<<v[i];
        cout << '\n';
    }
    return 0;
}

发表于 2021-01-19 22:03:27 回复(0)
Java 解法
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);
        }
    }
}




发表于 2020-03-18 11:27:49 回复(0)
我不生产代码,我只是代码的搬运工😂
#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;
}

发表于 2019-06-22 07:14:58 回复(0)
#include<bits/stdc++.h>
using namespace std;
#define M 100000
int main()
{
int a[M];
int N;
long index,i,j;
long carry,temp;
while(cin>>N)
{
index = 1;
carry = 0;
a[0]=1;
for(i=1;i<=N;i++)
{
for(j=0;j<index;j++)
{
temp = a[j]*i;
a[j]= (temp+carry)%10;
carry = (temp+carry)/10;
}
while(carry)
{
a[index++]=carry%10;
carry/=10;

}
}
for(i=index-1;i>=0;--i)
cout<<a[i];
cout<<endl;
}
return 0;
}
编辑于 2019-03-31 10:32:18 回复(0)
//大数乘法

#include<stdio.h>
#define MaxSize 1000
const int MOD = 10000;
typedef struct
{
    int data[MaxSize];
    int len;
}BigInt;
BigInt multiply(BigInt x, int y)
{
    int i, g = 0, z;
    for(i = 0; i < x.len; i++)
    {
        z = x.data[i] * y + g;
        x.data[i] = z % MOD;
        g = z / MOD;
    }
    while(g)
    {
        x.data[i++] = g % MOD;
        g /= MOD;
    }
    x.len = i;
    return x;
}
int main(void)
{
    int n, i;
    BigInt r;
    while(~scanf("%d", &n))
    {
        r.data[0] = 1;
        r.len = 1;
        for(i = 1; i <= n; i++)
            r = multiply(r, i);
        printf("%d", r.data[r.len - 1]);
        for(i = r.len - 2; i >= 0; i--)
            printf("%04d", r.data[i]);
        printf("\n");
    }
    return 0;
}

发表于 2019-01-06 16:05:43 回复(0)
因为大数阶乘肯定超过了整数范围,将结果6位6位一存,然后依次打印出来
#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;
    }
}

发表于 2018-03-26 23:07:09 回复(1)
#include<stdio.h>
#include<string.h>
struct bigInteger{
    int digit[1000]; //按四位一个单位来保存数值
    int size;//下一个我们未使用的数组单元
    void init(){
        for(int i=0;i<1000;i++) digit[i]=0;
        size=0;
    }
    void set(int x){
        init();
        do{
            digit[size++]=x%10000;
            x/=10000;
        }while(x!=0);
    }
    void output(){
        for(int i=size-1;i>=0;i--){
            if(i!=size-1) printf("%04d",digit[i]);
            else printf("%d",digit[i]);
        }
        printf("\n");
    }
    bigInteger operator * (int x) const{   //高精度整数与普通整数的乘积
        bigInteger ret;
        ret.init();
        int carry=0;
        for(int i=0;i<size;i++){
            int tmp=x*digit[i]+carry;
            carry=tmp/10000;
            tmp%=10000;
            ret.digit[ret.size++]=tmp;
        }
        if(carry!=0){
            ret.digit[ret.size++]=carry;
        }
        
        return ret;
    }
}a;
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        a.init();
        a.set(1);
        for(int i=1;i<=n;i++){
            a=a*i;
        }
        a.output();
    }
    return 0;
}

发表于 2018-03-14 21:59:14 回复(1)
#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;
       
    }
}

发表于 2018-03-12 19:48:20 回复(0)
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);
         }
    }
}

发表于 2018-02-26 15:25:00 回复(0)

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));
        }
    }
}
发表于 2017-12-23 16:43:58 回复(1)
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));
    }
}

发表于 2017-11-13 16:17:05 回复(0)
#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");
    }
}
编辑于 2019-03-13 10:39:04 回复(0)
#1000的阶乘为10的2568次方
try:
    while True:
        num,result = int(input()),1
        while num > 1:
            result *= num
            num -= 1
        print(result)
except Exception:
    pass

编辑于 2018-10-09 21:21:16 回复(0)
一个足够大的数组,从0位开始分别设为个位,十位。。,每次乘一个数都从低位开始向高位进行递推
 #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;
} 

发表于 2017-02-25 14:21:28 回复(0)
肯定超64位整数范围,所以要用大数阶乘。
用long数组存储阶乘结果,数组中的每个数存储阶乘的4位10进制数,不足的用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;
}

发表于 2016-09-01 10:31:44 回复(6)

python 三行解法:

import math,sys
for i in sys.stdin.readlines():
    print(math.factorial(int(i.strip())))
编辑于 2017-09-08 10:51:13 回复(2)
#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;
}
发表于 2019-04-06 16:25:30 回复(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;
}

发表于 2020-04-06 23:55:13 回复(0)

问题信息

难度:
109条回答 18949浏览

热门推荐

通过挑战的用户

查看代码