• 栈 && 教授的测试


    卡特兰数:https://blog.csdn.net/wu_tongtong/article/details/78161211


    https://www.luogu.org/problemnew/show/P1044

    n的答案就是C[n]

    证明的话,设n的答案为ans[n],只要考虑最后一个出栈的数(设为x),那么显然大于x的数在出栈序列中相邻,小于x的数在出栈序列中也相邻,所以这个x产生的贡献为ans[x]*ans[n-x-1];总答案ans[n]=ans[0]*ans[n-1]+ans[1]*ans[n-2]+...+ans[n-1]*ans[0]=C[n]


    http://210.33.19.103/contest/985/problem/5

    教授的测试

      转眼之间,新学期已经过去几个月了,F大学计算机系的W教授决定对他的学生进行一次测试。为了测试学生对树结构的认识,同时也检验他们的编程能力,教授把测试的内容定为:要求学生们编程按编号顺序打印出节点个数不少于m的所有二叉树。

      二叉树编号规则如下:

      仅有一个元素的树编号为1。

      当满足以下条件之一时,定义二叉树a的编号比b大:

        1. a的节点数比b多。

        2. 若a的节点数与b相等,且a的左子树编号比b的左子树大。

        3. a的节点数和左子树编号都和b相等,且a的右子树编号比b的右子树大。

      二叉树的元素用大写X表示。

      例如:

      打印二叉树的格式为:

      ( 左子树 ){若左子树为空,则省略} X{根} ( 右子树 ){若右子树为空,则省略}

      例如在上图中,编号为2 的树可表示为:X(X);

             编号为3 的树可表示为:(X)X;

             编号为5 的树可表示为:X((X)X);

      当然当m较大时,检验答案对错的工作也是很繁重的,所以教授只打算对其中的若干个编号的二叉树进行抽查,他想麻烦你在测试开始前把标准答案先准备好(教授的测试卷会事先交给你)。

    输入格式:

      输入文件为教授的测试卷,至少1行,至多10行,每行一个数N(1<=N<=10^8),即要抽查的二叉树的编号,以零结束。

    输出格式:

      输出文件是你求出的标准答案,对每一个编号输出其对应的二叉树,每个二叉树占一行,零不用输出。

    样例输入:

    2
    5
    0

    样例输出:

    X(X)
    X((X)X)

    数据范围:

    1<=N<=10^8

    时间限制:

    1000

    空间限制:

    65536

    这回的卡特兰数比较显然,但是实现有一些复杂?

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 #include<string>
     6 using namespace std;
     7 #define fi first
     8 #define se second
     9 #define mp make_pair
    10 #define pb push_back
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 typedef pair<int,int> pii;
    14  
    15 ll f[30],g[30];
    16 ll m,n;
    17 void dfs(ll n,ll k)
    18 {
    19     //if(n==0)  return "";
    20     ll tt=0,tn=0;
    21     while(tt+f[tn]*f[n-tn-1]<=k-1)   tt+=f[tn]*f[n-tn-1],tn++;
    22     if(tn)  putchar('('),dfs(tn,(k-tt-1)/f[n-tn-1]+1),putchar(')');
    23     putchar('X');
    24     if(n-tn-1)  putchar('('),dfs(n-tn-1,(k-tt-1)%f[n-tn-1]+1),putchar(')');
    25 }
    26 int main()
    27 {
    28     ll i,j;
    29     f[0]=1;
    30     for(i=1;i<=20;i++)
    31     {
    32         for(j=0;j<i;j++)
    33         {
    34             f[i]+=f[j]*f[i-j-1];
    35         }
    36     }
    37     g[1]=f[1];
    38     for(i=2;i<=20;i++)   g[i]=f[i]+g[i-1];
    39     while(1)
    40     {
    41         scanf("%lld",&n);
    42         if(n==0)    break;
    43         m=0;
    44         while(g[m+1]<=n-1)   m++;
    45         m++;
    46         dfs(m,n-g[m-1]);
    47         puts("");
    48     }
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    ROM定制开发教程-Android adb命令用法与实例解析
    Android内存优化—dumpsys meminfo详解
    adb命令查看手机应用内存使用情况
    【特征检测】BRISK特征提取算法
    焦虑症
    基于Lua的游戏服务端框架简介
    流量
    学习React Native必看的几个开源项目
    那些离开私企进入国企的人,现在都过得怎么样了?
    分布式系统中有关一致性的理解
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9544411.html
Copyright © 2020-2023  润新知