洛谷P5018 对称二叉树
不多扯题目 直接题解= =
1.递归
由题目可以得知,子树既可以是根节点和叶节点组成,也可以是一个节点,题意中的对称二叉子树是必须由一个根节点一直到树的最底部所组成的树。
这样一来就简单了,我们很容易就能想到用递归的方法
1.枚举根节点,判断其左右两个孩子节点 是否存在 以及是否相等. 若存在并且点权相等,则一直递归左右两个孩子节点的左右两个孩子节点 .
重复上述判断。
2.判断好对称二叉树后,就可以计算以该节点为根节点的对称二叉子树的节点数量并取最优值了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 1e6 + 10;//习惯性用定义法 当然也可以用const
int v[N], l[N], r[N];
//v[i]:节点i权值;l[i]:编号为i的节点的左孩子的编号;r[i]:编号为i的节点的右孩子的编号
int n,ans = ;
bool pd; //判断是否为对称二叉子树
int cnt(int x) { //计算以x为根节点的对称二叉子树的节点数
int sum ;
if (l[x]!=-) sum+=cnt(l[x]);
if (r[x]!=-) sum+=cnt(r[x]);
return sum+; //算上根节点
} void check(int x, int y) { //判断对称二叉子树
if (x==-&&y==-) return ; //到底了 结束
if (x==-||y==-||v[x]!=v[y]) { //不对称
pd = false;
return;
}
check(l[x], r[y]);
check(r[x], l[y]);
} int main() {
cin>>n;
for (int i=;i<=n;++i)
cin>>v[i];
for (int i=;i<=n;++i)
cin>>l[i]>>r[i];
ans = ; //至少有一个对称(一个节点)
for(int i=; i<=n;++i) {//枚举对称二叉子树的根节点
if (l[i]!=-&&r[i]!=-&&v[l[i]]==v[r[i]]){
pd=true; //先默认为是对称二叉子树
check(l[i], r[i]);
if (pd)
ans=max(ans, cnt(i)); //如果是对称二叉子树就可以计算节点数取最大值了
}
}
cout<<ans;
return ;
}
check(l[x],r[y]);
check(r[x],l[y]);
判断对称二叉子树时,应该是镜面对称的
所以在check时直接镜面对称即可
2dfs
如果一个二叉树是对称的,那么对于深度相同的两个节点u,v,必定有lson(u)lson(u)与rson(v)rson(v),rson(u)rson(u)与lson(v)lson(v),并且val_u=val_v:
int read()
{
int x=0,f=1;
char ch=getchar();
while('0'>ch||'9'<ch){
if (ch=='-')
f=-1;
ch=getchar();
}//判断正负
while('0'<=ch<='9'){
x=x*10+ch-48;
ch=getchar();
}//纯数字相加
return x*f;
}
int n,son[1000050][2],val[1000050],size[1000050];
//son[i][0]为i的左儿子
//son[i][1]为i的右儿子
void dfs(int u) //分别从左右扫一遍
{
size[u]=1;
if(son[u][0]!=-1)
{
dfs(son[u][0]);
size[u]+=size[son[u][0]];//size进入下一步dfs前先把当前状态改变
}
if (son[u][1]!=-1)
{
dfs(son[u][1]);
size[u]+=size[son[u][1]];
}
}
bool check(int u,int v)
{
if (u==-1&&v==-1)//特判
return true;
if (u!=-1&&v!=-1&&val[u]==val[v]&&check(son[u][0],son[v][1])&&check(son[u][1],son[v][0]))
return true;
return false;
}
int main()
{
n=read();
for (int i=1;i<=n;i++)
val[i]=read();
for (int i=1;i<=n;i++)
{
son[i][0]=read();
son[i][1]=read();
}
dfs(1);
int ans=0;
for (int i=1;i<=n;i++)
if(check(son[i][0],son[i][1]))
ans=max(ans,size[i]);
cout<<ans<<endl;
return 0;
}
然而我觉得这个近乎爆搜的打法还不如递归好使而且对我来说还挺难想= =
3.hash
可以直接hash树的形态,即分中序遍历1(先进左子树)和中序遍历2(先进右子树)记录hash值,对于每一个节点,若是此节点的左儿子的中序遍历1的hash值等于右儿子的中序遍历2的hash值,说明这个点为根的树是对称的(然而我用递归通过的= =所以hash就没打代码= =)
洛谷P5018 对称二叉树的更多相关文章
- 洛谷P5018 对称二叉树——hash
给一手链接 https://www.luogu.com.cn/problem/P5018 这道题其实就是用hash水过去的,我们维护两个hash 一个是先左子树后右子树的h1 一个是先右子树后左子树的 ...
- NOIP2018普及T4暨洛谷P5018 对称二叉树题解
题目链接:https://www.luogu.org/problemnew/show/P5018 花絮:这道题真的比历年的t4都简单的多呀,而且本蒟蒻做得出t4做不出t3呜呜呜... 这道题可以是一只 ...
- 洛谷 P5018 对称二叉树(搜索)
嗯... 题目链接:https://www.luogu.org/problem/P5018 其实这道题直接搜索就可以搜满分: 首先递归把每个点作为根节点的儿子的数量初始化出来,然后看这个节点作为根节点 ...
- 【洛谷P5018 对称二叉树】
话说这图也太大了吧 这题十分的简单,我们可以用两个指针指向左右两个对称的东西,然后比较就行了 复杂度O(n*logn) #include<bits/stdc++.h> using name ...
- 洛谷 P5018 对称二叉树
题目传送门 解题思路: 先计算每个点的子树有多少节点,然后判断每个子树是不是对称的,更新答案. AC代码: #include<iostream> #include<cstdio> ...
- 2021.08.09 P5018 对称二叉树(树形结构)
2021.08.09 P5018 对称二叉树(树形结构) [P5018 NOIP2018 普及组] 对称二叉树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 求一棵子树,关 ...
- 【洛谷P5018】对称二叉树
题目大意:定义对称二叉树为每个节点的左右子树交换后与原二叉树仍同构的二叉树,求给定的二叉树的最大对称二叉子树的大小. 代码如下 #include <bits/stdc++.h> using ...
- 题解 洛谷P5018【对称二叉树】(noip2018T4)
\(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...
- [洛谷P1040] 加分二叉树
洛谷题目链接:加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di ...
随机推荐
- String 对象-->大小比较
1.定义和用法 规则:从左至右依次对比相同下标处的字符,当两个字符不相等时,哪个字符的ASCII值大,那就哪个字符串就大. 返回值为1,左边大于右边 返回值为-1,右边大于左边 返回值为0,则相等 举 ...
- 【python实现卷积神经网络】批量归一化层实现
代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...
- frame/iframe多表单切换
应用场景: 在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位.这时就 ...
- Ubuntu上mysql, 通过python连接报错Can't connect to MySQL server on xxx (10061)
通过sqlyog连接ubuntu上的mysql报错 试了试python直接连接也报同样的错 那应该就是ubuntu上mysql服务自己的问题了 查看mysql 版本 mysql -V root@clo ...
- [php] phpStudy+XDebug配置
一.配置前说明: 1.phpStudy集成了XDebug扩展,所以不用单独下载XDebug. 2.打开XDebug扩展:其它选项菜单 > PHP扩展 > Xdebug 二.配置步骤: ph ...
- 【题解】P2602 数字计数 - 数位dp
P2602 [ZJOI2010]数字计数 题目描述 给定两个正整数 \(a\) 和 \(b\) ,求在 \([a,b]\) 中的所有整数中,每个数码(digit)各出现了多少次. 输入格式 输入文件中 ...
- 移动(appium)自动化测试-爬虫的另一种手段
appium自动化测试环境搭建: 1.Python环境(推荐2.7)和jdk. 2.Adb工具的下载:自己单独下载adb.夜神模拟器自带和Android sdk 3.Apk安装介质:真机.Androi ...
- web前端该怎么入门?web前端入门教程(非常详细)
初学编程的小伙伴经常会遇到的问题,1.没资源 2.没人带 3.不知道从何开始 ,小编也是从新手期过来的,所以很能理解萌新的难处,现在整理一些以前自己学习的一些资料送给大家,希望对广大初学小伙伴有帮助! ...
- 使用Idea当中的快捷键快速查看继承关系或其图表的两种方法
一.Idea当中有两种方法可以查看继承关系 在Idea当中选中一个类,然后按Ctrl+H,可以快速查看当前所选类的继承关系,如下图: 同样选中一个类,按CTRL+ALT+U,即可生成当前类的继承关 ...
- 十分钟通过一个实际问题,真正教会大家如何解决Bug
前言 这篇文章从实际问题 -> 问题解决步骤 -> 问题解决思路,帮助大家能够明白如何在程序中发现问题,定位问题,解决问题.并真正理解那些问题解决思路. 首先说说这个实际问题是什么,又是怎 ...