【算法竞赛入门经典】阶乘的精确值

问题描述



输入不超过1000的正整数n,输出n! = 1x2x3x4x···xn的精确结果.

样例输入:5

样例输出:120

算法分析



我们需要解决两个问题:

  • 怎么保存结果
  • 乘法过程是怎样的
  • 对于第一个问题:因为1000的阶乘是无法用整数保存的,用double也一样,它的位数会高达两千多位,保存阶乘值的位数,我们只能使用数组,这里使用一个大小为3000的数组;
    对于第二个问题:我们可以模拟数学乘法过程,以1为基础数,并存入数组,从2开始,依次去乘以现有基础数的数组里的每一位,设置一个进位标识,然后将结果保存在数组里;

    第一位存储个位数,然后依次是十位、百位、千位等,最后的结果由后往前输出,输出时需要将后面多余的0去掉。(从个位存起也可以避免无意义的0和有意义的0的混合,如5的阶乘为120,存在数组里为0、1、2,如果就是按照120存的话,最后一个0会与剩余的2997个0混淆,加大处理难度)

    代码实现


    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    const int maxn = 3000;
    int f[maxn];
    
    int main(){
        int i, j, n;
        while (scanf_s("%d", &n)){
            memset(f, 0, sizeof(f));
            f[0] = 1;
            for (i = 2; i <= n; i++){
                //乘以i
                int c = 0;  //c是进位
                for (j = 0; j < maxn; j++){
                    int s = f[j] * i + c;   //s是3000位依次来乘以i且加上进位
                    f[j] = s % 10;          //当前位存储个位
                    c = s / 10;             //进位标识
                }
            }
    
            for (j = maxn - 1; j >= 0; j--){
                if (f[j]) break;    //从后往前,依次排除掉数为0的位
            }
            //输出结果
            for (i = j; i >= 0; i--)
                printf("%d", f[i]);
            printf("\n");
        }
        system("pause");
        return 0;
    }
    
    时间: 2024-12-29 07:32:38

    【算法竞赛入门经典】阶乘的精确值的相关文章

    算法竞赛入门经典_4.3_递归

    看代码 #include <stdio.h> int f(int n){ return n == 0?1:f(n-1)*n; } int main() { printf("%d\n", f(5)); return 0; } 上面f函数使用了递归,递归由两部分组成,一是递归头,二是递归体. 我们使用gcc调试工具 H:\编程书籍学习\算法竞赛入门经典2代码\算法入门经典第四章>b f 'b' 不是内部或外部命令,也不是可运行的程序 或批处理文件. H:\编程书籍学习\算

    算法竞赛入门经典+挑战编程+USACO

    下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发.   一.UVaOJ http://uva.onlinejudge.org  西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ.   二.<算法竞赛入门经典> 刘汝佳  (UVaOJ  351道题)  以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html   "AO

    (Step1-500题)UVaOJ+算法竞赛入门经典+挑战编程+USACO

    下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinejudge.org 西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ. 二.<算法竞赛入门经典> 刘汝佳  (UVaOJ  351道题)  以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html “AOAPC I”是刘汝佳(大

    算法竞赛入门经典 程序4-1 组合数

    算法竞赛入门经典 程序4-1 组合数 其中求一个数的阶乘多次出现,为了方便以及保证程序整洁,将其作为一个函数编写 #include<iostream> using namespace std; long long factorial(int n) { long long m=1; for(int i=1;i<=n;i++) { m*=i; } return m; } long long c(int n,int m) { return factorial(n)/(factorial(m)*

    《算法竞赛入门经典第二版》 P35 习题2-4 子序列的和(subsequence)

    /* <算法竞赛入门经典第二版> P35 习题2-4: 输入两个正整数 n < m < 10^6,输出 (1/n)^2 + 1/(n+1)^2 +……+ 1/m^2,保留5位小数. 输入包含多组数据,结束标志为 m=n=0. 有错欢迎指出^_^ */ #include<stdio.h> int main() { int m,n,i,j=1; while(scanf("%d%d",&m,&n) != EOF) { double sum

    《算法竞赛入门经典(第二版)》pdf

    下载地址:网盘下载 内容简介  · · · · · · <算法竞赛入门经典(第2版)>是一本算法竞赛的入门与提高教材,把C/C++语言.算法和解题有机地结合在一起,淡化理论,注重学习方法和实践技巧.全书内容分为12 章,包括程序设计入门.循环结构程序设计.数组和字符串.函数和递归.C++与STL入门.数据结构基础.暴力求解法.高效算法设计.动态规划初步.数学概念与方法.图论模型与算法.高级专题等内容,覆盖了算法竞赛入门和提高所需的主要知识点,并含有大量例题和习题.书中的代码规范.简洁.易懂,不

    《算法竞赛入门经典》动态规划复习

    codevs 4979 数塔 1 #define N 100 2 #include<iostream> 3 using namespace std; 4 #include<cstdio> 5 int a[N][N],b[N][N],n; 6 int main() 7 { 8 scanf("%d",&n); 9 for(int i=1;i<=n;++i) 10 for(int j=1;j<=i;++j) 11 { 12 scanf("

    算法竞赛入门经典训练指南

    最近在看算法竞赛入门经典训练指南这本书,书中不错的算法我将在博客中发布,和大家共同学习. 题目: 在你的王国里有一条n个头的恶龙,你希望雇一些骑士把它杀死(即砍掉所有头).村里有m个骑士可以雇佣,一个能力值为m的骑士可以砍掉一个直径不超过x的头,且需要支付x个金币.如何雇佣骑士才能砍掉恶龙的所有头,且需要支付的金币最少?注意,一个骑士只能砍一个头(且不能被雇佣两次). 输入格式: 输入包含多组数据.每组数据的第一行为正整数m和n(1<=m,n<=20 000):以下m行每行为一个整数,即恶龙每

    算法竞赛入门经典-训练指南(10881-Piotr&#39;s Ants)

    题目大意: 一根长度为L的木棍一堆蚂蚁爬,向左或向右,速度都为1,若两蚂蚁碰撞则同时转头(转身时间忽略不计),问T时间之后每只蚂蚁的位置: 输入:t,(t个样例),每个样例输入 L,T,n,接下来是n行每行两个数据,一个POS(位置),一个dir(方向): 输出:按输入顺序输出每只蚂蚁的最终位置,若处于碰撞状态则输出Turning,掉下去输出"Fell off": 解题思路: 本题类似于<挑战程序设计>的一道水题(POJ -1852  Ants),思路题:不过本题输入并不一

    棋盘覆盖问题(算法竞赛入门经典)

    在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其它方格不同,则称该方格为一特殊方格,称该棋盘为一特殊棋盘.显然特殊方格在棋盘上出现的位置有 4^k 种情形.因而对任何 k>=0 ,有 4^k 种不同的特殊棋盘.下图所示的特殊棋盘为 k=2 时 16 个特殊棋盘中的一个. 在棋盘覆盖问题中,要用下图中 4 中不同形态的 L 型骨牌覆盖一个给定的特殊棋牌上除特殊方格以外的所有方格,且任何 2 个 L 型骨牌不得重叠覆盖.易知,在任何一个 2^k * 2^k 的棋盘中,用到的 L 型