zoj 1500 Pre-Post-erous!

1 篇文章 0 订阅

题意:一个k叉树,给定其前序和后序遍历,问其中序遍历方式有多少种。

思路:给定前序和中序无法唯一的确定一棵k叉树,但是每一个结点所在的深度

      却是唯一的。本题可用递归进行计算。每次递归获得每层结点分布的可能性。

      举例 :13 abejkcfghid jkebfghicda

     

     显然a,b容易确定,由后序知 j,k,e必定为 b 的后代。对 j,k,e 递归可获得j,k,e的位置关系。同理其它元素都可以确定自己所在的层数。

     对于每一层,计算组合数C(m,n)可知(即从m个中选n个),这里的 m表示的是m叉树,而n 则表示该层结点数。


#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
int k;

int C( int m,int n )
{
    int i,mul=1;
    for( i=0;i<n;i++ )
        mul*=(m-i);
    for( i=n;i>=1;i-- )
        mul/=i;
    return mul;
}

int solve( int m,char *pre,char *post )
{
    int i=1,j=0,re=1,son=0; //i为pre下标,j为post下标
                            //re统计结果,son表示子树个数。
    while( i<m )
    {
        while( post[j]!=pre[i] )
            j++;
        son++;
        re*=solve( j+2-i,pre+i,post+i-1 );
        i=j+2;
    }
    return re*C( k,son );
}

int main()
{
    char pre[30],post[30];
    while( scanf( "%d",&k ) && k )
    {
        scanf( "%s%s",pre,post );
        printf( "%d\n",solve( strlen(pre),pre,post ) );
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值