HEX
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;
}