牛客小白月赛1

https://www.nowcoder.com/acm/contest/85#question

所有代码:

https://pan.baidu.com/s/1B0a4CZ6HFev0iwDdtDwBcA

 

E.

已知∠A、∠B、∠C是△ABC内角,求证:tanA/2 * tanB/2 + tanB/2 * tanC/2 + tanC/2 * tanA/2 = 1

 

G.

统一公式!

坐标为

0

-1 1

-2 0 -2

-3 -1 1 3

……

 

三个阶段

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <set>
 7 #include <map>
 8 #include <list>
 9 #include <stack>
10 #include <queue>
11 #include <vector>
12 #include <algorithm>
13 #include <iostream>
14 using namespace std;
15 #define ll long long
16 #define minv 1e-6
17 #define inf 1e9
18 const ll mod=1e9+7;
19 const long maxn=8e2+10;
20 
21 int f[4*maxn][maxn],i,j,s,t,b=3;
22 
23 ///统一公式,这样可以大大减少代码编写量
24 //row=j len=k
25 void work(int k)
26 {
27     t=-k+1;
28     for (s=1;s<=k;s++,t+=2)
29     {
30         scanf("%d",&f[j][t]);
31         f[j][t]+=max(f[j-2][t],max(f[j-1][t-1],f[j-1][t+1]));
32 //        printf("\t%d",f[j][t]);
33     }
34 //    printf("\n");
35 }
36 
37 int main()
38 {
39     int n;
40     scanf("%d",&n);
41 
42     ///j为负数,是为了使用方便
43     ///f[i][j]的地址: address of f+ Len * (i*Y+j),即j可以为负数
44     for (i=1;i<=4*n-3;i++)
45         for (j=-n;j<=n;j++)
46             f[i][j]=-inf;
47 
48     scanf("%d",&f[b][0]);
49     for (i=2,j=b+1;i<=n;i++,j++)
50         work(i);
51 
52     for (i=1;i<=n-1;i++)
53     {
54         work(n-1);
55         j++;
56         work(n);
57         j++;
58     }
59 
60     for (i=n-1;i>=1;i--,j++)
61         work(i);
62     printf("%d",f[j-1][0]);
63     return 0;
64 }
65 /*
66 len= totally different
67 2
68 -1
69 -1 -1
70 -1
71 -1 -1
72 -1
73 
74 4
75 1
76 1 1
77 1 1 1
78 1 1 1 1
79 1 1 1
80 1 1 1 1
81 1 1 1
82 1 1 1 1
83 1 1 1
84 1 1 1 1
85 1 1 1
86 1 1
87 1
88 
89 3
90 8
91 3 7
92 9 100 -5
93 -2 4
94 -1 100 2
95 100 0
96 5 -3 5
97 100 6
98 4
99 */

 

I.
已知一个没有深度限制的栈的入栈序列为 ,且  不能第一个出栈。求合法的出栈序列个数。答案对  取模。

 

首先,我们设f(n)=序列个数为n的出栈序列种数。(我们假定,最后出栈的元素为k,显然,k取不同值时的情况是相互独立的,也就是求出每种k最后出栈的情况数后可用加法原则,由于k最后出栈,因此,在k入栈之前,比k小的值均出栈,此处情况有f(k-1)种,而之后比k大的值入栈,且都在k之前出栈,因此有f(n-k)种方式,由于比k小和比k大的值入栈出栈情况是相互独立的,此处可用乘法原则,f(n-k)*f(k-1)种,求和便是Catalan递归式。

 

考虑卡特兰数,H(n) 表示n 个数的合法出栈序列个数。而本题中第一个元素不能第一个出
栈,所以应当减掉第一个元素出栈的方案数。可以发现若第一个元素先出栈,那么剩下的元素依
然可以构成一个n 􀀀 1 个元素的入栈序列,所以第一个元素出栈的方案数就等于n 􀀀 1 个元素合
法出栈序列的数量。所以答案为H(n) - H(n - 1) 。

 

卡特兰数

F(n)->F(n+1)的方法。

 

//https://baike.baidu.com/item/%E5%8D%A1%E7%89%B9%E5%85%B0%E6%95%B0/6125746?fr=aladdin
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll long long
#define minv 1e-6
#define inf 1e9
const ll mod=998244353;
const long maxn=1e5+5;

int sum=0;
ll a[maxn],f[maxn],x,y;

void gcd(ll a,ll b)
{
    if (b==0)
    {
        x=1;
        y=1;
    }
    else
    {
        gcd(b,a%b);
        ll r;
        r=x;
        x=y;
        y=r-a/b*y;
    }
}

ll ni(ll s)
{
    gcd(mod,s);
    return (y%mod+mod)%mod;
}


int main()
{
    int i,j,q;
    //C(2n,n)/(n+1)
    //C(2n,n)=C(2n-2,n-1)
    a[1]=2;
    for (i=2;i<=1e5;i++)
    {
        /*
        2i-2..i  2i..i+1
        _______  ______
        i-1..1   i..1
        */
        a[i]=a[i-1]*2*(2*i-1)%mod *ni(i)%mod;///每次乘法后进行求模运算
        f[i]=a[i]*ni(i+1)%mod;
    }
    scanf("%d",&q);
    for (i=1;i<=q;i++)
    {
        scanf("%d",&j);
        printf("Case #%d: %lld\n",i,(f[j]-f[j-1]+mod)%mod);///注意相减要加mod
    }
    return 0;
}

 

posted @ 2018-08-22 17:10  congmingyige  阅读(159)  评论(0编辑  收藏  举报