2019.7.27

T1.随 (rand)

T2.单(single)

T3.题(problem)

本来人家是简、单、题,硬生生被改成随单题。

T1、T2太难了,不在考虑范畴,直接看T3。

T3.题(problem)

  找规律、推式子、敲代码、得到部分分。

    typ=1的时候,明显想到Catlan数,EZ。

    typ=0的时候,是前几天的考题visit的简化版。

       经WD大佬的指点,式子也可写为(C(2n,n))^2;  如下图,

       每走一步由原来的(1,0)、(-1,0)、(0,1)、(0,-1)变为(1,-1)、(-1,1)、(1,1),(-1,-1) 这样就可以分别组合数并乘起来。

       

    typ=2的时候,递推(想不到啊)

    f[i]表示走了i步回到原点的方案数 中途可能回到过原点多次) ,
    枚举第一次回到原点时走过的步数j(为了存在合法解,j为偶数) 
       则此时方案数为f[i-j]*catalan(j/2-1)   累加答案时要乘4(四个方向)。(看不懂看代码,就懂了

 

    typ=3的时候,枚举横向移动了多少步 ,各个方向步数就定了。

      方案数为C(n,i)*catalan(i/2)*catalan((n-i)/2) (i为横向步数)

     

      推荐一篇博客:https://blog.csdn.net/wu_tongtong/article/details/78162593

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define RE register
 4 using namespace std;
 5 const int mod=1e9+7;
 6 const int maxn=2000010;
 7 ll n,typ;
 8 ll inv[maxn],fac[maxn];
 9 ll fast_pow(ll x,ll b,ll p){
10     ll s=1;
11     while(b){
12         if(b&1) s=s*x%p;
13         x=x*x%p;
14         b>>=1;
15     }
16     return s%p;
17 }
18 void init(){
19     fac[0]=fac[1]=inv[0]=1;
20     for(int i=2;i<=n;i++) fac[i]=fac[i-1]%mod*i%mod;
21     inv[n]=fast_pow(fac[n],mod-2,mod);
22     for(int i=n-1;i>=0;i--) 
23         inv[i]=inv[i+1]*(i+1)%mod;
24 }
25 ll C(ll mm,ll nn){
26     if(mm==0) return 1;
27     if(mm>nn) return 0;
28     return fac[nn]%mod*inv[mm]%mod*inv[nn-mm]%mod;
29 }
30 ll Cat(ll x){
31     return (C(x,x*2)*(fac[x]*inv[x+1]%mod)%mod)%mod;
32 }
33 ll anss=0;
34 ll f[1010];//f[i]表示走i*2步回到原点 ,也就是,最远距离 
35 int main(){
36 //    freopen("in.txt","r",stdin);
37     scanf("%lld%lld",&n,&typ);
38     init();
39     if(typ==0){
40         ll a,b,c,d;//上,下,右,左
41         for(a=0;a<=n/2;a++){
42             b=a,c=(n-a*2)/2,d=c;
43             ll ans=C(a,n)%mod*C(b,n-a)%mod*C(c,n-a-b)%mod;
44             anss=(anss+ans)%mod;
45         } 
46         printf("%lld
",(anss%mod+mod)%mod);
47         return 0;
48     }
49     if(typ==1){
50         ll ans=Cat(n/2);
51         printf("%lld
",(ans%mod+mod)%mod);
52         return 0;
53     }
54     if(typ==2){
55         ll m=n/2;
56         f[0]=1;
57         for(int i=1;i<=m;i++){
58             for(int j=1;j<=i;j++)
59                 f[i]=(4*f[i-j]%mod*Cat(j-1)%mod+f[i]%mod)%mod;//为什么要j-1,是因为不计算原点,从1开始到的最远距离 
60         }
61         printf("%lld",f[m]%mod);
62         return 0;
63     }
64     if(typ==3){
65         ll ans=0;
66         for(int i=0;i<=n;i+=2)
67         ans=(ans+C(i,n)%mod*Cat(i/2)%mod*Cat((n-i)/2)%mod)%mod;
68         printf("%lld",(ans%mod+mod)%mod);
69         return 0;
70     }
71 }
View Code
原文地址:https://www.cnblogs.com/sdfzjdx/p/11264954.html