1 条题解

  • 0
    @ 2025-5-15 11:31:39

    解题思路:

    问题转化:

    将圆上2n2n个点配对问题转化为卡塔兰数计算

    需要处理nn=11100100的大数计算

    高精度设计:

    选择BASE=1000010000平衡计算效率和存储空间

    采用数组模拟大数运算

    乘法和除法都基于万进制实现

    关键算法:

    乘法:从低位到高位逐位相乘处理进位

    除法:从高位到低位逐位处理余数

    递推计算:确保每一步都精确无误差

    解题方法:

    高精度处理:

    使用BASE=1000010000的万进制存储大数

    每个数字用长度为101101的数组表示(可存储最多400400位数)

    采用倒序存储(a[n][100]a[n][100]存储最低44位)

    递推计算:

    初始化前3项:h(1)=1h(1)=1, h(2)=2h(2)=2, h(3)=5h(3)=5

    使用递推公式:h(n)h(n) = h(n1)×(4n2)/(n+1)h(n-1)×(4n-2)/(n+1)

    分两步计算:先乘(4n2)(4n-2),再除(n+1)(n+1)

    输入输出处理:

    预处理所有11-100100的结果

    读取输入直到1-1结束

    输出时跳过前导零,保持44位格式

    C++代码实现:

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    #define BASE 10000
    int a[101][101];
    void multiply(int k,int num)
    {               //乘法
        int ans=0;
        for (int i=100;i>=0;i--)
        {
            ans+=a[k-1][i]*num;
            a[k][i]=ans%BASE;
            ans/=BASE;
        }
    }
    void devide(int k,int num)
    {               //除法
        int div=0;
        for (int i=0;i<=100;i++)
        {
            div=div*BASE+a[k][i];
            a[k][i]=div/num;
            div%=num;
        }
    }
    void init()
    {
        memset(a,0,sizeof(a));
        a[1][100]=1;
        a[2][100]=2;
        a[3][100]=5;
        int num;
        for (int i=4;i<=100;i++)
        {                   //公式h(n)=h(n-1)*(4*n-2)/(n+1);
            num=(4*i-2);
            multiply(i,num);
            num=i+1;
            devide(i,num);
        }
    }
    int main()
    {
        int n;
        init();
        while (~scanf("%d",&n)&&n!=-1)
        {
            int pos;
            for (int i=100;i>=0;i--)
                if (!a[n][i])           //倒着遍历,因为数字长度不是太多,毕竟只是到n的上限是100
                {
                    pos=i+1;
                    break;
                }
                printf("%d",a[n][pos]);
                for(int i=pos+1;i<=100;i++)
                    printf("%04d",a[n][i]);        //保证与base的长度相同,因为可能会有0在里边
                    printf("\n");
        }
     
        return 0;
    }
    • 1

    信息

    ID
    1085
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者