Trees Made to Order

Trees Made to Order

 组合计数相关

http://acm.pku.edu.cn/JudgeOnline/problem?id=1095

Description

We can number binary trees using the following scheme: 
The empty tree is numbered 0. 
The single-node tree is numbered 1. 
All binary trees having m nodes have numbers less than all those having m+1 nodes. 
Any binary tree having m nodes with left and right subtrees L and R is numbered n such that all trees having m nodes numbered > n have either Left subtrees numbered higher than L, or A left subtree = L and a right subtree numbered higher than R. 

The first 10 binary trees and tree number 20 in this sequence are shown below:


图片Your job for this problem is to output a binary tree when given its order number.

 

###"prj_1.h"

 

#pragma once

#include"<iostream>

#include<List>

#include<vector>

#include<iterator>

#include<numeric>

#include<algorithm>

#include<string>

using namespace std;

int pD(const list<int> & left, const list< int> & right)

{

     return inner_product( left.begin(), left.end() , right.begin(), 0);

}

 

string get_printX( list<int> & val, int totalNodes, int remain)

{

     if( totalNodes == 0)

         return "";

     if( totalNodes == 2 && (remain == 2 /*|| remain == 0*/) )

         return "(X)X";

     if( totalNodes == 2 && remain == 1)

         return "X(X)";

     if( totalNodes == 1 && ( remain == 0 || remain == 1) )

         return "X";

 

 

     string m_str("X");

     int lfnodes ,rtnodes;

     {

         list<int> temp( val);

         temp.reverse();

         list< int>::iterator pos, pos1;

         int sum = 0;

         int bf_sum = sum;

         int cnum = 0; //  computing  left and right nodes

         for(  pos1 = temp.begin(), pos = val.begin() ; pos != val.end();cnum ++, ++pos, ++pos1)

         {

              bf_sum = sum;

              sum += (*pos1 ) * ( *pos);

              if( sum >= remain)

              {

                   lfnodes =  cnum;

                   rtnodes = totalNodes - 1 - cnum;

                   break;

              }

         }

 

         string lfstr ,rtstr;

         vector< int> vec_temp ;

         vector<int> vec_val;

         copy( temp.begin(), temp.end() ,back_inserter(vec_temp));

         copy( val.begin() ,val.end() ,back_inserter( vec_val) );

         int lfremain ,rtremain;  // computing left and  right ranking number each

         {

 

              int tt = vec_temp[ cnum];

              lfremain = 1;

              rtremain = 0;

              int ___remain = remain - bf_sum;

              while( ___remain -- > 0)

              {

                   rtremain ++;

                   if( rtremain > tt)

                   {

                       rtremain = 1;

                       lfremain += 1;

                   }

                  

              }

         }

 

         list<int> temp_list_lf, temp_list_rt;

         temp_list_lf.clear();

         temp_list_rt.clear();

         vec_temp.clear();

         {

              copy(val.begin(), val.end() ,back_inserter(vec_temp));

 

              {

                   copy( vec_temp.begin() ,vec_temp.begin() + lfnodes ,back_inserter( temp_list_lf) );

        

                   copy( vec_temp.begin() ,vec_temp.begin() + rtnodes , back_inserter( temp_list_rt));

              }

         }

 

         lfstr = get_printX( temp_list_lf, lfnodes, lfremain);

         rtstr = get_printX( temp_list_rt, rtnodes,  rtremain);

 

         if( rtnodes == 0)

         {

              string tp("(");

              tp += lfstr;

              tp += ")";

              tp += m_str;

              m_str = tp;

         }

         else if( lfnodes == 0)

         {

              m_str += "(";

              m_str += rtstr;

              m_str += ")";

         }

         else

         {

              string tp("(");

              tp += lfstr;

              tp += ")";

              tp += m_str;

              m_str = tp;

              m_str += "(";

              m_str += rtstr;

              m_str += ")";

         }

     }

     return m_str;

}

 

 void prj_1( int num)

{

 

     list< int> ret;

     ret.clear();

     ret.push_back(1);

     ret.push_back(1);

     ret.push_back(2);

     int sum = 3;

     list< int > tp( ret);

     int count = 2;

     int bf_sum = sum;

     do{

         tp = ret;

         tp.reverse();

         bf_sum = sum;

         sum += pD( ret , tp);

         ret.push_back( pD( ret, tp));

         count ++;

     }while( sum < num);

 

     tp.clear();

     vector<int> vtp( ret.begin() ,ret.end() );

     copy( vtp.begin(), vtp.end() - 1 ,back_inserter(tp));

     cout<<"num ="<<num<<" Nodes ="<<count<<"remain ="<<num - bf_sum<<endl;

     std::cout<<get_printX(tp ,count , num - bf_sum)<<endl;

}

###main.cpp

#pragma once

#include "stdafx.h"

#include"prj_1.h"

int _tmain(int argc, _TCHAR* argv[])

{

     int num1 = 4;

     int num2 = 500000;

     //num2 = 31117532;

     forint i = num1; i <= num2 ;i ++)

         prj_1( i);

 

     return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值