zoukankan      html  css  js  c++  java
  • [数论][组合数学]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.

    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;
    }
    转载请注明出处:https://www.cnblogs.com/lllxq/
  • 相关阅读:
    python set()、len()、type()、保留小数、EOFError
    代码学习与感悟
    你的代码的风格
    python 面向对象的类
    ubuntu 上下左右键变成ABCD
    python运算符
    python 数据类型详解
    python关键字
    python 设计及调试的一些小技巧
    python-list
  • 原文地址:https://www.cnblogs.com/lllxq/p/8901690.html
Copyright © 2011-2022 走看看