zoukankan      html  css  js  c++  java
  • 网格

    题目连接:

    https://www.acwing.com/problem/content/1317/

    Description

    某城市的街道呈网格状,左下角坐标为 A(0,0),右上角坐标为 B(n,m),其中 n≥m。

    现在从 A(0,0) 点出发,只能沿着街道向正右方或者正上方行走,且不能经过图示中直线左上方的点,即任何途径的点 (x,y) 都要满足 x≥y,请问在这些前提下,到达 B(n,m) 有多少种走法。

    Input

    仅有一行,包含两个整数 n 和 m,表示城市街区的规模。
    (1≤m≤n≤5000)

    Output

    输出一个整数,表示不同的方案总数。

    Sample Input

    6 6
    

    Sample Output

    132
    

    题解

    可以利用卡特兰数的这条性质:卡特兰数 Catalan number。得到(n,m)关于红线的对称点:先将所有下移一格:(n,m-1),红线过(0,0),得到对称点:(m-1,n),再上移一格对称点最终:(m-1,n+1)。答案为C(n+m,m)-C(n+m,m-1)。
    首先求精确值,需要用到高精度,n,m比较大,需要枚举阶层质因子来求。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=10010;
    int st[N],prime[N],tot,sum[N],a[N],b[N],ans[N];
    void get_Prime(){
        for(int i=2;i<N;++i){
            if(!st[i]) prime[++tot]=i;
            for(int j=1;prime[j]<=N/i;++j){
                st[prime[j]*i]=1;
                if(!(i%prime[j])) break;
            }
        }
    }
    int calc(int x,int y){
        int cnt=0;
        while(x){
            cnt+=x/y;
            x/=y;
        }
        return cnt;
    }
    void mul(int arr[],int b){
        for(int i=0;i<N;++i){
            arr[i]*=b;
            if(i>0)
            arr[i]+=arr[i-1]/10,arr[i-1]%=10;
        }
    }
    void solve(int arr[],int a,int b){
        for(int i=1;i<=tot;++i){
            int p=prime[i];
            sum[i]=calc(a,p)-calc(b,p)-calc(a-b,p);
        }
        arr[0]=1;
        for(int i=1;i<=tot;++i){
            for(int j=1;j<=sum[i];++j){
                mul(arr,prime[i]);
            }
        }
    }
    void print(int arr[]){
        int i=N-1;
        while(arr[i]==0&&i>=0) --i;
        while(i>=0) cout<<arr[i--];
        puts("");
    }
    int main(){
        get_Prime();
        int n,m;
        cin>>n>>m;
        solve(a,n+m,n);
        solve(b,n+m,m-1);
        for(int i=0;i<N;++i){
            ans[i]+=a[i]-b[i];
            if(ans[i]<0) ans[i+1]--,ans[i]+=10; 
        }
        print(ans);
        return 0;
    }
    
  • 相关阅读:
    c语言输入一个字符串,统计其字母,数字和其他字符的个数,并以柱状图输出
    c语言中的#ifdef和#ifndef
    宏定义#define
    c语言中的register int
    android SDK 更新的几个网址
    android studio启动不进行fetching Android sdk compoment information
    android eclipse ADT 安装maven插件失败
    Jsp 的映射
    Jsp 九大隐式对象
    Jsp 乱码处理
  • 原文地址:https://www.cnblogs.com/jjl0229/p/12724994.html
Copyright © 2011-2022 走看看