ps:因为oj评测不采用填空模式,本博文采用数组模拟树操作,无视题目的填空,有填空需求的同学请移步
首先根据输入的先序遍历递归建树,接下来是对不同出度的结点进行统计
递归遍历每个结点然后,看结点的儿子数量即可
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(x,y) memset(x,y,sizeof(x))
#define all(v) v.begin() , v.end()
#define pb(v) push_back(v)
#define INF 0x3f3f3f3f
#define int long long
#define lson p*2,l,mid
#define rson p*2+1,mid+1,r
typedef long long ll;
const int N = 1e5+10;
char s1[N];
int len1;//输入字符串长度
int n;
int num=0;
char tree[N];//数组存树
int cnt1=0;//出度为1数量
int cnt2=0;//出度为2数量
int cnt0=0;//出度为0数量
void build(int pos)//递归建树
{
num++;
if( num > len1) return ;//递归边界,输入字符读取完毕
if( s1[num] == '#')//建树边界
{
return;
}
//根据根左右的顺序建树
tree[pos] = s1[num];//当前结点赋值
build(pos*2);//建左子树
build(pos*2+1);//建右子树
}
void dfs(int pos )
{
if( tree[pos] =='\0' ) return;//如果当前结点空,递归结束
//如果当前结点有两儿子,cnt2++
if( tree[ 2*pos] !='\0' && tree[2*pos+1] !='\0') cnt2++;
//如果当前结点有一儿子,cnt1++
else if( tree[ 2*pos] !='\0' || tree[2*pos+1] !='\0') cnt1++;
//无儿子cnt0++
else cnt0++;
dfs(pos*2);//遍历左子树
dfs(pos*2+1);//遍历右子树
}
void solve()
{
build(1);
dfs(1);
cout<<cnt2<<endl;
cout<<cnt1<<endl;
cout<<cnt0<<endl;
}
signed main()
{
//!!!!!!!!!!!!!!!!!!!!!!
// freopen("data.txt","r",stdin);
//!!!!!!!!!!!!!!!!!!!!!!
IOS;
cin>>(s1+1);
len1 = strlen(s1+1);
solve();
}