PTA 深入虎穴 (正解)和树的同构
在上一篇博客中分享了尝试用单链表修改程序,虽然在Dev上运行没有错误,但是PTA设置的测试点有几个没有通过,具体不清楚问题出现在哪里,所以现在把之前正确的程序放在这里。
著名的王牌间谍 007 需要执行一次任务,获取敌方的机密情报。已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门。每一扇门背后或者是一个房间,或者又有很多条路,同样是每条路通向一扇门…… 他的手里有一张表格,是其他间谍帮他收集到的情报,他们记下了每扇门的编号,以及这扇门背后的每一条通路所到达的门的编号。007 发现不存在两条路通向同一扇门。
内线告诉他,情报就藏在迷宫的最深处。但是这个迷宫太大了,他需要你的帮助 —— 请编程帮他找出距离入口最远的那扇门。
输入格式:
输入首先在一行中给出正整数 N(<),是门的数量。最后 N 行,第 我行(1)按以下格式描述编号为 i 的那扇门背后能通向的门:
K D[1] D[2] ... D[K]
其中 K
是通道的数量,其后是每扇门的编号。
输出格式:
在一行中输出距离入口最远的那扇门的编号。题目保证这样的结果是唯一的。
输入样例:
13
3 2 3 4
2 5 6
1 7
1 8
1 9
0
2 11 10
1 13
0
0
1 12
0
0
输出样例:
12
根据题目要求和输入形式,分析数据存储结构,跟树结构相似,所以采用二叉树知识进行解题。
每行序号表示门序号,然后是这个门后面通向其他门个数,再来输入通向那些门。所以这个结构就像一个节点,然后它的孩子个数,跟树结构很像。
#include<iostream>
#include<queue>
using namespace std; typedef struct //结构体数组,一个数据域存放门数量,另外用一个指针指向存放通道门序号的数组
{
int doors;//门的数量
int *p; //指向后面门的编号序列
}node; int input(node *a,int n)//读入n扇门的信息 ,并返回跟所在门序号(下标)
{
int i,j;
bool *vi;
vi=new bool[n+];//找出根结点的辅助数组 for(i=;i<n+;i++)
vi[i]=false; for(i=;i<n+;i++)
{
cin>>a[i].doors;
if(a[i].doors)//门后面有通道
{
a[i].p=new int[a[i].doors];//申请存储门后面通道
for(j=;j<a[i].doors;j++)
{
cin>>a[i].p[j];
vi[a[i].p[j]]=true;
}
}
else //door后面没有通向其他门的通道
{
a[i].p=NULL;
} }
for(i=;i<n+;i++)//找出根结点所在下标(起点)
{
if(!vi[i]) return i;
}
} int level(node *a,int r)//从a[r]开始对a数组进行层次遍历,并返回遍历最后一个结点的序号
{//跟二叉树层次遍历相似,找到最远的门,也就是层次遍历最后的那个叶结点
queue<int> q;
int f,i;
q.push(r); while(!q.empty())
{
f=q.front();
q.pop(); if(a[f].doors) //t号门后面有通道门
{
for(i=;i<a[f].doors;i++)
{
q.push(a[f].p[i]);
}
}
}
return f;//遍历到最后一个门序号,即是深度最大叶结点
} int main()
{
node *a;//用于存储整棵树
int n,root;
cin>>n;
a=new node[n+];
root=input(a,n);
// cout<<root;
cout<<level(a,root);
return ;
}
给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。
例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
图1 图2
现给定两棵树,请你判断它们是否是同构的。
输入格式:
输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。
输出格式:
如果两棵树是同构的,输出“Yes”,否则输出“No”。
输入样例1(对应图1):
8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -
输出样例1:
Yes
输入样例2(对应图2):
8
B 5 7
F - -
A 0 3
C 6 -
H - -
D - -
G 4 -
E 1 -
8
D 6 -
B 5 -
E - -
H - -
C 0 2
G - 3
F - -
A 1 4
输出样例2:
No
这道题再次用到查找树的根结点的函数,跟之前完全一样,主要实现操作在于判断树同构的算法。
有以下几种情况:
1、两棵树为空,则同构
2、有一棵树为空,则不同构
3、都不为空,但是根结点名称不同,则不同构
4、都不为空,同构时的符合情况:
(1)左1=左2 且 右1=右2
(2)左1=右2 且 右1=左2
第4步判断操作可以基于前面3点,用递归方式实现。
#include<iostream>
#include<queue>
using namespace std; typedef struct
{
char name;
int l,r;
} node; int BuildTree(node T[]) //建立二叉树
{
int i,N;
bool check[]={false};//check数组用于查找树的根节点
char x,y;
cin>>N; if(N)//树结点个数不为0
{
for(i=;i<N;i++)
{
cin>>T[i].name>>x>>y; if(x!='-')//若结点不为空,将节点索引放入左子树结点
{
T[i].l=x-'';
check[T[i].l]=true;//记录此结点索引,在check数组将该位置置为true
}
else
{
T[i].l=-;//若结点为空,将其置为-1
} if(y!='-')//同上,放入右子树
{
T[i].r=y-'';
check[T[i].r]=true;
}
else
{
T[i].r=-;
}
}
for(i=;i<N;i++)//遍历check数组,除了根结点之外,其它元素为true或-1
{
if(!check[i]) return i;//返回根结点下标
}
}
else return -;// 若树为空,返回 -1 } int treetonggou(node t1[],node t2[],int x,int y)//判断两棵树是否同构
{
if(x==-&&y==-) return ;//两棵树为空,同构
else if(x==-||y==-) return ;//有一棵树为空,不同构
else if(t1[x].name!=t2[y].name) return ;//根结点名称不同,不同构
else//递归判断所在根结点是否符合
{
return((treetonggou(t1,t2,t1[x].l,t2[y].l))&&(treetonggou(t1,t2,t1[x].r,t2[y].r))//判断两棵树此结点情况:左=左并且右=右
||(treetonggou(t1,t2,t1[x].l,t2[y].r))&&(treetonggou(t1,t2,t1[x].r,t2[y].l)));//左=右并且右=左
}
} int main()
{
node t1[],t2[];
int r1,r2;
r1=BuildTree(t1);
r2=BuildTree(t2);//cout<<r1<<" "<<r2;
//cout<<treetonggou(t1,t2,r1,r2);
if(treetonggou(t1,t2,r1,r2)) cout<<"Yes";
else cout<<"No";
return ;
}
做这道题开始不是很顺利,问题出在我用递归方式不对,在第4步时候是这样的:
int treetonggou(node t1[],node t2[],int x,int y)
{
if(x==-&&y==-) return ;
else if(x==-||y==-) return ;
else if(t1[x].name!=t2[y].name) return ;
else
{
if((treetonggou(t1,t2,t1[x].l,t2[y].l))&&(treetonggou(t1,t2,t1[x].r,t2[y].r)))
return ;
if((treetonggou(t1,t2,t1[x].l,t2[y].r))&&(treetonggou(t1,t2,t1[x].r,t2[y].l)));
return ;
}
}
看是用了递归函数,之后一分析,其实没有用到前面基础进行递归,而是有自己的返回值了,没有用到递归的思想,在几个测试点没通过,因为没有考虑到各种情况,比如:
遍历结果相同,但树不同构;孩子结点相同,但根结点不同,树不同构。
之后几次修改,得到上面那个很长的return语句,最后通过。
PTA 深入虎穴 (正解)和树的同构的更多相关文章
- pta 编程题6 树的同构
其它pta数据结构编程题请参见:pta 题目请参见:树的同构 因题目中左右子树是按照下标给出,因此用数组存放树是更好的方法. 判断两棵树是否同构:用递归的方法.如果当前两个结点都为空,则返回TRUE: ...
- HDU 4251 --- 主席树(划分树是正解)
题意:查询区间中位数 思路:模板题,相当于区间第K大的数,主席树可以水过,但划分树是正解.但还没搞明白划分树,先上模板 #include <iostream> #include <c ...
- BZOJ3110 K大数查询 【线段树 + 整体二分 或 树套树(非正解)】
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- PTA 03-树1 树的同构 (25分)
题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/711 5-3 树的同构 (25分) 给定两棵树T1和T2.如果T1可以通过若干次左右 ...
- PTA 树的同构 (25分)
PTA 树的同构 (25分) 输入格式: 输入给出2棵二叉树树的信息.对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号):随后N行,第i行对应编号第 ...
- 【BZOJ-4059】Non-boring sequences 线段树 + 扫描线 (正解暴力)
4059: [Cerc2012]Non-boring sequences Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 440 Solved: 16 ...
- CodeForces - 633H :Fibonacci-ish II(正解:莫对+线段树)
Yash is finally tired of computing the length of the longest Fibonacci-ish sequence. He now plays ar ...
- 【PTA】浙江大学数据结构慕课 课后编程作业 03-树1 树的同构
题目内容 给定两棵树T1和T2.如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是"同构"的.例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A.B.G的左右 ...
- [刷题] PTA 03-树1 树的同构
程序: 1 #include <stdio.h> 2 #define MaxTree 10 3 #define ElementType char 4 #define Tree int 5 ...
随机推荐
- Java 精简Jre jar打包成exe
#开始 最近几天都在忙一个事情,那就是尝试精简jre,我想不明白为什么甲骨文官方不出exe打包工具... 网络上精简jre的文章很多,但是原创的似乎没几个,绝大多数都是转发同一个博客, 这里借鉴了不少 ...
- Jodd
Jodd = tools + ioc + mvc + db + aop + tx + json + html < 1.7 Mb Jodd is set of Java microframewor ...
- Node.js使用supervisor遭遇‘supervisor’不是内部或外部命令,如果解决?
如果你有 PHP 开发经验,会习惯在修改 PHP 脚本后直接刷新浏览器以观察结果,而你 在开发 Node.js 实现的 HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止 Node.js ...
- php curl_errno 60
问题描述 使用curl进行微信统一下单,curl 错误 curl_errno 60 错误码60 因为使用了证书配置项,所以要配置curl证书 解决方法 下载证书并配置php.ini ,配置curl证书 ...
- Canvas的基本用法
canvas没有设置宽度和高度的时候,会初始化宽度:300像素和高度:150像素.可以使用CSS来定义大小,但在绘制时图像会伸缩以适应它的框架尺寸:如果CSS的尺寸与初始画布的比例不一致,它会出现扭曲 ...
- 学习Javascript数据结构与算法(第2版)笔记(1)
第 1 章 JavaScript简介 使用 Node.js 搭建 Web 服务器 npm install http-server -g http-server JavaScript 的类型有数字.字符 ...
- 模板——无旋Treap
#include "bits/stdc++.h" using namespace std; inline int read(){ ,k=;char ch=getchar(); :, ...
- laravel 查询数据返回的结果
laravel查询数据返回的结果 在插入数据库的时候,发现查询数据返回的结果是一个对象;即使是空数据 返回的不是true或者false 那么要判断该结果是否查询有结果 该如果呢? 学习源头: http ...
- window 7 安装Jmeter并配置https录制脚本
安装与环境配置: http://blog.csdn.net/hhuangdanfeng/article/details/51564765 http://blog.csdn.net/u010573212 ...
- 记一次产品需求:图片等比缩放和CSS自适应布局16:9
前言 前阵子,产品跑过来问我现有的模板中没有图片模板,需要添加一个图片模板:然而,他要求图片在展示区最好能够实现随着窗口的变化而自动按图片比例等比缩放,并且居中展示图片.我当时想着,抛开技术实现层面, ...