首页 > 其他分享 >CSP历年复赛题-P1009 [NOIP1998 普及组] 阶乘之和

CSP历年复赛题-P1009 [NOIP1998 普及组] 阶乘之和

时间:2024-05-20 09:31:41浏览次数:13  
标签:P1009 int res vector result NOIP1998 阶乘 fac

原题链接:https://www.luogu.com.cn/problem/P1009

题意解读:

  利用高精度计算阶乘之和,需要用到高精度乘法(高精度乘低精度)、高精度加法。

  首先,思考不利用高精度如何解题,直观方法就是遍历i从1到n,每次乘i得到i的阶乘,然后累加到结果,代码如下:

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

int res; //结果
int fac = 1; //阶乘
int n;

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        fac *= i;
        res += fac;
    }
    cout << res;

    return 0;
}

  然后,将其中需要转变为高精度的地方进行替换,整数变量要替换为vector数组,乘法、加法操作替换为高精度函数操作,可得:

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

vector<int> res; //结果
vector<int> fac(1, 1); //阶乘
int n;

void mul(int i)
{

}

void add()
{

}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        mul(i);  //将fac乘以i
        add(); //将fac加到res上
    }
    for(int i = res.size() - 1; i >= 0; i--) cout << res[i];

    return 0;
}

  最后,实现mul、add函数进行高精度乘法、加法操作。

100分代码:

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

vector<int> res; //结果
vector<int> fac(1, 1); //阶乘
int n;

//mul函数实现fac = fac * b
void mul(int b)
{
    vector<int> result;
    int t = 0;
    for(int i = 0; i < fac.size(); i++)
    {
        t += fac[i] * b;
        result.push_back(t % 10);
        t /= 10;
    }
    while(t)
    {
        result.push_back(t % 10);
        t /= 10;
    }
    fac = result;
}

//add函数实现res = res + fac
void add()
{
    vector<int> result;
    int t = 0;
    int len = max(res.size(), fac.size());
    for(int i = 0; i < len; i++)
    {
        if(i < res.size()) t += res[i];
        if(i < fac.size()) t += fac[i];
        result.push_back(t % 10);
        t /= 10;
    }
    if(t) result.push_back(t);
    res = result;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        mul(i);  //将fac乘以i
        add(); //将fac加到res上
    }
    for(int i = res.size() - 1; i >= 0; i--) cout << res[i];

    return 0;
}

 

标签:P1009,int,res,vector,result,NOIP1998,阶乘,fac
From: https://www.cnblogs.com/jcwy/p/18201223

相关文章

  • CSP历年复赛题-P1010 [NOIP1998 普及组] 幂次方
    原题链接:https://www.luogu.com.cn/problem/P1010题意解读:输出一个正整数的2的幂次方表示,需要用到二进制数学知识,将整数拆解成2的次幂之和,幂次方也要进行拆解,因此容易想到通过递归处理。解题思路:先看样例,给定整数137,要拆解成2的幂次方之和,先考虑i使得刚好137>=2^i时,i取7,因此2......
  • python: 递归函数:阶乘
    一,认识递归函数1,什么是递归?递归的工作原理是,如果函数需要处理的问题大小合适,则直接求解并返回结果,否则将问题分解成两个或多个更小的子问题,并对子问题进行相同的处理,直到问题无法分解为止2,什么是递归函数:递归函数(recursivefunction)是指在函数体中可以调用自己的函数3,语......
  • 洛谷 P1012 [NOIP1998 提高组] 拼数 题解
    题目简述设有$n$个正整数$a_1\dotsa_n$,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。题目分析定义设$X$为数字$x$的字符串形式。$A+B$表示字符串$A$和字符串$B$相连组成的字符串。思路既然要构造最优解,显然如果有不优的情况的话,就需要对序列进行......
  • P1010 [NOIP1998 普及组] 幂次方
    题目:P1010[NOIP1998普及组]幂次方[NOIP1998普及组]幂次方题目描述任何一个正整数都可以用2的幂次方表示。例如137=27+23+2^0。同时约定次方用括号来表示,即a^b可表示为a(b)。由此可知,137可表示为2(7)+2(3)+2(0)进一步:$7=22+2+20(2^1用2表示),并且3=2+2^......
  • 关于求阶乘逆元
    以下思路背景均来自题目牡牛和牝牛预处理做法众所周知:\[C_n^m=\frac{n!}{m!(n-m)!}\]众所周知知:c++中除法很不稳定,所以需要逆元。所以真正在运用时,我们的函数会这么写:intC(inta,intb){ if(a<b) return0; returnjc[a]*ny[b]%mod*ny[a-b]%mod;}啊哦忘说要......
  • 蓝桥杯-【二分】求阶乘
     思路:对于有几个0,10一定会是5的整数倍,2的因子数一定比5的多,所以只要算5的个数即可, 30%,每个n都去算#include<bits/stdc++.h>usingnamespacestd;#definelllonglongllcheck(lln){//计算n!末尾有多少个0llcnt=0;while(n)cnt+=......
  • 172.阶乘后的零
    题目:给定一个整数 n ,返回 n! 结果中尾随零的数量。提示 n!=n*(n-1)*(n-2)*...*3*2*1示例1:输入:n=3输出:0解释:3!=6,不含尾随0示例2:输入:n=5输出:1解释:5!=120,有一个尾随0示例3:输入:n=0输出:0思路: 末尾零的个数实际上是......
  • 编写一个算法来计算 n 阶乘中尾随零的数量
    算法:编写一个算法来计算n阶乘中尾随零的数量解题思路:当n过大时,从1遍历至n,那么会超时,发现以下规律:n!=1*2*3*4*(1*5)*...*(2*5)*...*(3*5)...每隔5个数就会出现一个5,因此我们只需要通过n/5来计算存在存在多少个5个数,那么就对应的存在多少个......
  • 洛谷 P1008 [NOIP1998 普及组] 三连击
    这道题我们可以用桶排序来做,代码如下:#include<bits/stdc++.h>//万能头 usingnamespacestd;//好习惯 inta[10];//一个桶数组,来确定是否有重复的 intmain(){   ints1,s2,s3;//定三个函数,用于判断    intsum=0;//用于判断数字是否重复    for(int......
  • 阶乘(C++实现)
    阶乘是基斯顿·卡曼(ChristianKramp,1760~1826)于1808年发明的运算符号,是数学术语。一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。1808年,基斯顿·卡曼引进这个表示法。公式表示为:0!=1n!= ()阶乘运算在C++语言中的实现,代......