zoukankan      html  css  js  c++  java
  • 栈 && 教授的测试

    卡特兰数: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
  • 相关阅读:
    牛客网 二叉树的镜像 JAVA
    牛客网 反转链表 JAVA
    牛客网 调整数组顺序使奇数位于偶数前面 JAVA
    Integer to Roman LeetCode Java
    Valid Number leetcode java
    Longest Common Prefix
    Wildcard Matching leetcode java
    Regular Expression Matching
    Longest Palindromic Substring
    Add Binary LeetCode Java
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9544411.html
Copyright © 2011-2022 走看看