10:00~12:30
听一篇英语听力,做一套四级试卷。
12:30~14:30
教妹妹高中数学和英语。
14:30~18:30
做题。
第一题:
P1305
题目描述
输入一串二叉树,输出其前序遍历。
输入格式
第一行为二叉树的节点数 nn。(1 \leq n \leq 261≤n≤26)
后面 nn 行,每一个字母为节点,后两个字母分别为其左右儿子。
空节点用 *
表示
输出格式
二叉树的前序遍历。
输入输出样例
输入 #1复制
6 abc bdi cj* d** i** j**
输出 #1复制
abdicj
解题思路:输入的第一个字符就是根节点,然后根据前序遍历的特点先遍历左子树输出就可以。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n;
char a[30][4];
void find(char x)
{
if(x!='*')//节点有效
{
printf("%c",x);
for(int i=0;i<n;i++)
if(a[i][0]==x)
{
find(a[i][1]);//左子树
find(a[i][2]);//右子树
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%s",a[i]);
find(a[0][0]);
return 0;
}
第二题:
P1030
题目描述
给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度\le 8≤8)。
输入格式
22行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。
输出格式
11行,表示一棵二叉树的先序。
输入输出样例
输入 #1复制
BADC BDCA
输出 #1复制
ABCD
说明/提示
【题目来源】
NOIP 2001 普及组第三题
见下图
解题思路:见上图,后序遍历的最后一个节点是根节点,在中序遍历中,根节点的左边是他的左子树,右边是他的右子树,先序是根左右,每次输出父节点即可求出先序遍历的输出。先dfs左边,在dfs右边即可。
AC代码:
#include<bits/stdc++.h>
char a[100], b[100];
void dfs(int m1, int m2, int m3, int m4)
{
if (m1 > m2 || m3 > m4)//遍历完了返回
{
return;
}
printf("%c", b[m4]);//输出父节点
for (int k = m1; k <= m2; k++)
{
if (a[k] == b[m4])//中序中找到了父节点开始dfs
{
dfs(m1, k-1, m3, m3+k-m1-1);
dfs(k+1, m2, m3+k-m1, m4-1);
break;
}
}
}
int main(void)
{
scanf("%s",a);
scanf("%s",b);
int len = strlen(a) - 1;
dfs(0, len, 0, len);
return 0;
}
第三题:
P4913
题目描述
给出每个节点的两个儿子节点,建立一棵二叉树(根节点为 11),如果是叶子节点,则输入0 0
。建好树后希望知道这棵二叉树的深度。二叉树的深度是指从根节点到叶子结点时,最多经过了几层。
最多有 10^6106 个结点。
输入格式
无
输出格式
无
输入输出样例
输入 #1复制
7 2 7 3 6 4 5 0 0 0 0 0 0 0 0
输出 #1复制
4
解题思路:因为所求的是最多几层,果断想到了直接dfs每次都保存最多的数字,直接写出一直向左和向右遍历的dfs即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[100010][3];
int sum=1;
void dfs(int x,int y)//x代表节点,y代表深度
{
if(x==0) return;//叶子节点返回
sum=max(sum,y);//每次存储最大深度
dfs(a[x][0],y+1);//向左
dfs(a[x][1],y+1);//向右
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)//从1开始,根节点是1
scanf("%d%d",&a[i][0],&a[i][1]);
dfs(1,1);
printf("%d",sum);
return 0;
}