HEX


HEX

Time Limit: 4000MS  Memory Limit: 131072KB
Problem Description

On a plain of hexagonal grid, we define a step as one move from the current grid to the lower/lower-left/lower-right grid. For example, we can move from (1,1) to (2,1), (2,2) or (3,2).

In the following graph we give a demonstrate of how this coordinate system works.

Your task is to calculate how many possible ways can you get to grid(A,B) from gird(1,1), where A and B represent the grid is on the B-th position of the A-th line.

Input

For each test case, two integers A (1<=A<=100000) and B (1<=B<=A) are given in a line, process till the end of file, the number of test cases is around 1200.

Output

For each case output one integer in a line, the number of ways to get to the destination MOD 1000000007.

Example Input
1 1
3 2
100000 100000
Example Output
1
3
1
Hint
存个代码,提示就是选路问题,有三个走法,下,下左,下右。

用组合数学做

#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9+7;
const int maxn = 1e5+10;
typedef long long LL;
LL fac[maxn],Ni[maxn];
LL modxp(LL a,LL b,LL p){
    LL res = 1;
    while(b){
        if(b&1)
            res = (res*a)%p;
        b = b>>1;
        a = (a*a)%p;
    }
    return res;
}
LL niYuan(LL a, LL b){//费马小定理求逆元
    return modxp(a, b - 2, b);
}
void Init(){
    fac[0] = 1;
    Ni[0] = 1;
    for(int i = 1; i < maxn; i++){
        fac[i] = (fac[i-1]*i)%mod;
        Ni[i] = niYuan(fac[i],mod);
    }
}
LL C(LL a,LL b){
    return ((fac[a]*Ni[b])%mod*Ni[a-b]% mod)%mod;
}
int main(){
    LL x,y,ans,a,b,c,pian;
    Init();
    while(~scanf("%lld %lld",&y,&x)){
        ans = 0;
        if(y%2 == 0){
            if(x>=y/2+1)
                pian = (x-(y/2+1))*2+1;
            else
                pian = (y/2-x)*2+1;
        }
        else{
            pian = abs((y+1)/2-x)*2;
        }
        a = pian;
        b = 0;
        while(a+b<=y-1){
            c = (y-1-a-b)/2;
            ans = ans+(C(a+b+c,a)*C(b+c,b))%mod;
            ans = ans%mod;
            a++;
            b++;
        }
        printf("%lld\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值