题目描述
俗话说得好,姜还是老的辣。
HolmiumTS很喜欢种姜,但他自己却从来不吃姜。他年初的时候往土里埋了一块姜。
每隔一段时间,他就会把土里的姜全部挖出来,每一块都切成两半,然后再埋进土里。每次埋之前,他都会测定每一块姜的辣度。
经过k次之后,他得到了一棵有2k个叶子的完全二叉树,每个结点都记录了对应姜的辣度,他称之为“族谱”。
现在有两张这样的“族谱”,你需要判断两张“族谱”是否相等。
“族谱”相等的定义:
1、对于在族谱叶子上的姜,如果他们的辣度相同则相等。
2、对于其它的姜,如果他们的辣度相等且他们产生的仔姜的辣度也对应相等,则他们相等。(这里的对应不要求顺序,即一块的左侧仔姜可以对应另一块的右侧仔姜)
3、如果一块姜在族谱的叶子上而另一块不在叶子上,则他们不相等。
4、两份族谱相等当且仅当两份族谱位于根的姜相等。
输入
第一行包含一个整数,为数据的组数T
接下来包含3T行,每三行对应一组数据
每组数据第一行包含一个整数k,含义见题目描述。
接下的两行每行包含2(k+1)−1个非负整数,对应一份族谱的层次遍历。
输出
对于每组数据,输出Yes或No,表示族谱是否相同。
输入样例
2
1
1 2 3
1 3 2
2
1 2 2 3 3 4 4
1 2 2 3 4 3 4
输出样例
Yes
No
数据范围与约定
1<=T<=100
1<=k<=10
保证辣度非负且在int范围内
提示
两份族谱能否转成一个易于判断的族谱形式?
问就是不吃葱姜蒜.jpg
思路分析
根据助教的Hint(Hint每次都让迷惑的我更加迷惑2333),把数组转化成容易判断的二叉树本树形式。
再用从根节点处依次递归,判断两个二叉树是否相等(不得不说虽然菜鸡的我难以掌握递归,但它真的太强辽)
AC代码
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *lchild,*rchild;
};
typedef struct node Node;
typedef struct node *Nodeptr;
int nums_a[2100], nums_b[2100];
Nodeptr Create(int a[],int i,int n);//生成二叉树
int isEqual(Nodeptr t1,Nodeptr t2);//判断两个二叉树是否相等
int main()
{
int i,t,k,n=1;
scanf("%d",&t);
while(t--)
{
n=1;
scanf("%d",&k);
for(i=0;i<k+1;i++)
n*=2;
n--;
for(i=0;i<n;i++)
scanf("%d",&nums_a[i]);
for(i=0;i<n;i++)
scanf("%d",&nums_b[i]);
Nodeptr head_a = NULL, head_b = NULL;
head_a = Create(nums_a,0,n);
head_b = Create(nums_b,0,n);
if(isEqual(head_a,head_b)==1) printf("Yes\n");
else printf("No\n");
}
}
Nodeptr Create(int a[],int i,int n)
{
if(i>=n) return NULL;
Nodeptr t = (Nodeptr)malloc(sizeof(Node));
t->data=a[i];
t->lchild = Create(a,2*i+1,n);
t->rchild = Create(a,2*i+2,n);
return t;
}
int isEqual(Nodeptr t1,Nodeptr t2)
{
if(t1==NULL&&t2==NULL) return 1;
if(t1==NULL||t2==NULL) return 0;
if(t1->data==t2->data)
{
return (isEqual(t1->lchild,t2->lchild)&&isEqual(t1->rchild,t2->rchild))||(isEqual(t1->lchild,t2->rchild)&&isEqual(t1->rchild,t2->lchild));
}
return 0;
}