题意:二叉排序树(没叫错名吧),问有多少种不同形状的树(如图)。
题目分析:貌似是今年world final的原题(今年考了好多原题呀,各种没做过),大牛们说的前序遍历的方法没有听明白。这是我自己的理解。首先建二叉树,按数组递归的插入,建树的同时记录左右子树下有多少节点。对比时比较每个节点对应的左右节点个数是否相同,全相同就说明2个树长的一样,否则不一样。由于插入和查询都需要递归调用,时间复杂度貌似比较高,但是一共就50个树,最多1000个节点,随便搞一下都可以做出来。
//
// main.cpp
// Prototypes analyze
//
// Created by teddywang on 16/6/8.
// Copyright © 2016年 teddywang. All rights reserved.
//
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef struct node{
node *left,*right;
int l,r,num;
}trienode;
trienode *s[100];
void init(trienode *rt)
{
rt->left=rt->right=NULL;
rt->l=rt->r=rt->num=0;
}
void insert(trienode *rt,int m)
{
trienode *r;
if(m> rt->num )
{
rt->r++;
if(rt->right==NULL)
{
r=new node;
init(r);
r->num=m;
rt->right=r;
}
else insert(rt->right,m);
}
else
{
rt->l++;
if(rt->left==NULL)
{
r=new node;
init(r);
r->num=m;
rt->left=r;
}
else insert(rt->left,m);
}
}
int cmp(trienode *a,trienode *b)
{
int flag1=0,flag2=0;
if(a->l!=b->l||a->r!=b->r) return 0;
if(a->l==1||a->l==0)
flag1=1;
else flag1=cmp(a->left,b->left);
if(a->r==1||a->r==0)
flag2=1;
else flag2=cmp(a->right,b->right);
if(flag1==1&&flag2==1) return 1;
else return 0;
}
int main()
{
int m,n,N;
cin>>N;
while(N--)
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
s[i]=new node;
init(s[i]);
int t[100];
cin>>t[0];
s[i]->num=t[0];
for(int j=1;j<m;j++)
{
cin>>t[j];
insert(s[i],t[j]);
}
}
int vis[100],ans=0;
for(int i=0;i<n;i++)
{
int flag1=0;
for(int j=i+1;j<n;j++)
{
if(!vis[j]&&cmp(s[i],s[j])==1)
{
vis[j]=1;
flag1=1;
}
}
if(flag1==0) ans++;
}
cout<<ans<<endl;
for(int i=0;i<n;i++)
free(s[i]);
}
}