您的位置:首页 > 编程语言 > C语言/C++

VIJOS-P1156

2016-06-23 14:58 253 查看

题目描述

猩猩,骆驼,还有泡泡经常喜欢在饭后到操场上散步,由于猩猩的走路姿势最突出最显眼,理所应当的成为他们中的主角,所以我的题目就说猩猩散步了。(骆驼和泡泡别有意见哈,和猩猩争啥……)   当然,话说回来,猩猩在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位,速度不会慢的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 算法