51nod 机器人走方格 V3

基准时间限制:1 秒 空间限制:131072 KB 分值: 80  难度:5级算法题
 收藏
 关注
N * N的方格,从左上到右下画一条线。一个机器人从左上走到右下,只能向右或向下走。并要求只能在这条线的上面或下面走,不能穿越这条线,有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10007的结果。
Input
输入一个数N(2 <= N <= 10^9)。
Output
输出走法的数量 Mod 10007。
Input示例
4
Output示例
10

解析:
卡特兰数+卢卡斯定理
代码:
/**
if(gcd(b,m)!=1)
  (a/b)%m=a%(bm)/b
*/
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long LL;
const LL MAXN=1e9+5;
const LL p=1e4+7;
LL MOD;
LL quick(LL a,LL b)
{
    LL c=1;
    while(b)
    {
        if(b&1)
        c=(a*c)%MOD;
        a=(a*a)%MOD;
        b>>=1;
    }
    return c;
}
LL inv(LL a)
{
    a=a%MOD;
    return quick(a,MOD-2);
}
LL C(LL a,LL b)
{
    LL s1=1,s2=1;
    for(LL i=0;i<b;i++)
    {
        s1=(s1*(a-i))%MOD;
        s2=(s2*(b-i))%MOD;
    }
    return s1*inv(s2)%MOD;
}
LL Lucas(LL n,LL m)
{
    return m?(Lucas(n/MOD,m/MOD)*C(n%MOD,m%MOD))%MOD:1;
}
LL gcd(LL a,LL b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    LL n,m,ans;
    while(scanf("%lld",&n)!=-1)
    {
        n--;
        if(gcd(n+1,p)==1)
        {
            MOD=p;
            ans=Lucas(2*n,n);
            ans=(ans*2*inv(n+1))%MOD;
        }
        else
        {
            MOD=(n+1)*p;
            ans=Lucas(2*n,n);
            ans=(ans*2)%MOD/(n+1);
        }
        printf("%lld\n",ans);
      
    }
    return 0;
}

注意:
没有考虑gcd的值时也过了,数据有点水
 我的gcd!=1的情况,可能,大概会是错的,( ´▽` )因为并没有测数据

还差一篇要补
                                                                                                                                                                    ----------2018、1、27

猜你喜欢

转载自blog.csdn.net/qq_38144740/article/details/79177811
今日推荐