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.
Sample Input
1 1 3 2 100000 100000
Sample Output
1 3 1
Hint
Source
题意:求从(1,1)走到(a,b)一共有多少种方案数
思路:从当前一格可以向左下,右下,正下方移动,则
(1,1)+x*(1,0)+y*(2,1)+z*(1,1)=(a,b)
所以:x+y=a-b, y+z = b-1; 0<=y<=min(b-1,a-b)
对于每个y时,方案数ans=C(x+y+z,x)*C(y+z,x);
由于组合数比较大,用逆元思想来处理
代码:
#include<cstdio> #include<cstring> #include<string> #define mod 1000000007 using namespace std; typedef long long LL; const int N = 100000; LL fact[N+5],inv[N+5]; LL q_pow(LL x,LL y){ LL ans=1; while(y){ if(y&1) ans=ans*x%mod; x=x*x%mod; y>>=1; } return ans; } void init(){ fact[0]=1; for(int i=1;i<=N;i++) fact[i]=fact[i-1]*i%mod; inv[N]=q_pow(fact[N],mod-2); for(int i=N-1;i>=0;i--){ inv[i]=inv[i+1]*(i+1); inv[i]%=mod; } } LL C(int n,int m){ return ((fact[n]*inv[m])%mod*inv[n-m])%mod; } int main(){ init(); int a,b; while(scanf("%d%d",&a,&b)!=EOF){ LL ans=0; int n=min(a-b,b-1); for(int y=0;y<=n;y++){ int z=b-1-y; int x=a-b-y; ans+=(C(x+y+z,x)*C(z+y,y))%mod; ans%=mod; } printf("%lld\n",ans); } return 0; }