VIJOS-P1156

13 篇文章 1 订阅

题目描述

猩猩,骆驼,还有泡泡经常喜欢在饭后到操场上散步,由于猩猩的走路姿势最突出最显眼,理所应当的成为他们中的主角,所以我的题目就说猩猩散步了。(骆驼和泡泡别有意见哈,和猩猩争啥……)   当然,话说回来,猩猩在OI上的能力也是不容低估的,你看,散步时还会想一道与此相关的问题,这是道经典的不能再经典的问题了。   在一个m×n的矩阵上,猩猩在左下角的顶点出现了,他只能沿着路径向上或者向右走,他的目标是“蠕动”到右上角的顶点,问他有多少路径可以选择。嗯,这个、这个、这个似乎地球人都知道怎么做,但是请注意,我有个条件没给呢!m和n现在的最大范围是50000,这可怎么办?仔细想想吧。
.

输入

只有一行,包含两个整数m和n,其上限均为50000

输出

由于最后的答案数目过大,所以只检查后100位,输出时每行十个数字,没空格间隔,共十行,如果答案位数没超过100位,则需要在空位上补0。

样例输入

7 4

样例输出

0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000330

#include<iostream>
#include <cstring>

using namespace std;

const long a[66]= {0  ,2  ,3  ,5  ,7  ,11 ,13 ,17 ,19 ,23 ,
                   29 ,31 ,37 ,41 ,43 ,47 ,53 ,59 ,61 ,67 ,
                   71 ,73 ,79 ,83 ,89 ,97 ,101,103,107,109,
                   113,127,131,137,139,149,151,157,163,167,
                   173,179,181,191,193,197,199,211,223,227,
                   229,233,239,241,251,257,263,269,271,277,
                   281,283,293,307,311,313};

void mul(long a[1000],long n)
{ long i;
    for (i=1; i<=a[0]; i++)
        a[i]=a[i]*n;
    for (i=1; i<a[0]; i++) {
        a[i+1]+=a[i]/10;
        a[i]%=10;
    }
    while (a[a[0]]>9) {
        a[a[0]+1]=a[a[0]]/10;
        a[a[0]]%=10; a[0]++;
    }
    if (a[0]>101)
        a[0]=101;
}

int main(){
    long i,j,n,m,all,h[200000],nn,mm,ans[1000];
    scanf("%ld %ld",&n,&m);
    all = n + m;
    memset(h,0,sizeof(h));
    for (i = n+1; i <= all; i++)
    {
        nn=i;
        for (j = 1; j <= 65; j++)
        {
            while (nn%a[j] == 0)
            {h[a[j]]++; nn/=a[j];
                if (nn==1)
                    break;}
            if (nn==1)
                break;}
        if (nn!=1)
            h[nn]++;
    }
    for (i=1; i<=m; i++)
    {
        mm=i;
        for (j=1; j<=65; j++)
        {
            while (mm%a[j]==0)
            {h[a[j]]--; mm/=a[j];
                if (mm==1)
                    break;}
            if (mm==1)
                break;}
        if (mm!=1)
            h[mm]--;
    }
    ans[0]=1;
    ans[1]=1;
    for (i=1; i<=100000; i++)
        while (h[i]>0) {
            mul(ans,i);
            h[i]--;
        }
    for (i=100; i>=1; i--) {
        printf("%ld",ans[i]);
        if (i%10==1)
            printf("\n");
    }
}
    题目做多了,人都麻木了,这么简单的逻辑都无法快速看出来。。。
    求的是C(n+m,m)也可以写成C(n+m,n)是一样的,具体编程思路就是先开个素数表记录平方在100000以内的素数,然后把分子每个因数分解质因数,相应的HASH表+1,而分母分解时则-1,如果分解到最后剩下的不是1,那么剩下的数肯定也是一个质数,直接相应HASH+1或-1.最后HASH里不为0的都去乘,只保留最后100位,速度不会慢的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值