洛谷1009题

洛谷1009题

哈哈哈哈,我胡汉三又回来啦
这个题目如果用c++/c做的话,小伙伴们会面临什么问题呢,首先就是数据太长了,C++的long long类型是无法存储的哦(亲身测试了),相信聪明的你,立马反应“用大整数呀”。给聪明的你点赞。可是C++的大整数真的太让人头疼了,超级长,一点都不友好,试想一下,比赛的时候,你要写将近一百行的大整数运算,隔壁Java的牲口小伙伴竟然用BigInteger。所以来一场C++的自救吧。
下面上正菜

#include<iostream>
//不要用万能头文件!!很多比赛已经不支持了,而且那玩意会增加你的运行时间
//悄悄告诉你,我胡汉三又回来了
using namespace std;
int a[100000], n, i, y, xy[100000], s[100000];//注意这里s[0]表示n-1项相加的答案长度,a[0]表示第n项n!的长度
//s表示答案,a表示阶乘,先算出阶乘,放在a里,再把s和它相加,更新s
void add()//表示s=s+a
{
    int i;
    memset(xy, 0, sizeof(xy));//xy为辅助数组,先将a+s放入xy,再将s更新为xy

    //注意这里s[0]表示n-1项相加的答案长度,a[0]表示第n项n!的长度
    xy[0] = max(s[0], a[0]);//更长的为xy数组长度
    for (i = 1; i <= xy[0]; i++)
    {
        xy[i] += s[i] + a[i];//将每一位相加
        xy[i + 1] = xy[i] / 10;//进位
        xy[i] %= 10;//进位
    }
    while (xy[xy[0] + 1] > 0) //进位
    {
        xy[xy[0] + 2] = xy[xy[0] + 1] / 10;
        xy[xy[0] + 1] %= 10;
        xy[0]++;
    }
    s[0] = xy[0];//长度也要更新
    for (i = 1; i <= xy[0]; i++) s[i] = xy[i];//将xy给s
}
int main()//愉快的开始了主程序
{
    cin >> n;
    a[0] = 1;//将数组初值赋好
    a[1] = 1;//这里一定要是1,不然算阶乘的时候一直为0
    s[0] = 1;
    s[1] = 0;
    for (y = 1; y <= n; y++) //这里是高精度乘法
    {
        memset(xy, 0, sizeof(xy));//xy为辅助数组,先将a+s放入xy,再将s更新为xy
        xy[0] = a[0];
        //这个for循环的作用:计算相应n!
        for (i = 1; i <= a[0]; i++)
        {
            xy[i] += a[i] * y;//算阶乘
            xy[i + 1] = xy[i] / 10;//进位
            xy[i] %= 10;
        }

        //这里的while循环:判断是否需要更新长度
        while (xy[xy[0] + 1] > 0)//进位 
        {
            xy[xy[0] + 2] = xy[xy[0] + 1] / 10;
            xy[xy[0] + 1] %= 10;
            xy[0]++;
        }

        //这个for循环:将xy[i]的每一个都传递给a[i]
        for (i = 1; i <= xy[0]; i++) a[i] = xy[i];
        a[0] = xy[0];

        add();//进行高精度加法,这里add()运行了多次,所以s[0]的数是不断更新的
    }
    for (i = s[0]; i >= 1; i--) cout << s[i];//这里是反向输出哦,别不小心哦
    cout << endl;//换行
    return 0;//其实我不喜欢写它,不过好多比赛都要有它(⊙︿⊙)
}
上一篇:常见的概率公式及其推导(马尔科夫HMM系列课程拓展)


下一篇:Android笔记——创建第一个Android Studio项目