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
思路:若只能向↙或↘走,从(1,1)->(x,y),总共要走tot=(x-1)步,其中向↘要走r=(y-1)步,向↙要走l=(x-y)步,那么总的走法就是C(tot,r)(或C(tot,l))。
若还能向↓走,因为一步↓相当于一步↙加上一步↘,所以若向↓走i步,总共就只要走tot'=(tot-i)步,向↘走r'=(r-i)步,向↙走l'=(l-i)步,(其中0<=i<=min(l,r)),
那么总的走法数就是C(tot',i)+C(tot'-i,r)(表达形式不止一种)。
AC代码:
#include <iostream> #include<cstdio> #include<algorithm> #define mod 1000000007 #define ll long long using namespace std; ll f[100050]; ll revf[100050]; ll qpow(ll x,ll n){ ll ret=1; while(n){ if(n&1) ret=(ret*x)%mod; x=(x*x)%mod; n>>=1; } return ret; } ll rev(ll x){ return qpow(x,mod-2); } void init(){//预处理 f[0]=1; revf[0]=rev(f[0]); for(ll i=1;i<=100010;i++){ f[i]=i*f[i-1]%mod; revf[i]=rev(f[i]); } } ll C(ll n,ll m){ return f[n]%mod*revf[m]%mod*revf[n-m]%mod; } int main() { init(); ll x,y; while(scanf("%lld%lld",&x,&y)!=EOF){ ll tot_=x-1; ll r_=y-1; ll l_=x-y; ll down_max=min(l_,r_); ll ans=0; for(ll i=0;i<=down_max;i++){ ll tot=tot_-i; ll l=l_-i; ll r=r_-i; ans=(ans+C(tot,i)%mod*C(tot-i,l)%mod)%mod; } printf("%lld ",ans); } return 0; }