★实验任务

可怜的 Bibi 刚刚回到家,就发现自己的手机丢了,现在他决定回头去搜索 自己的手机。
现在我们假设 Bibi 的家位于一棵二叉树的根部。在 Bibi 的心中,每个节点 都有一个权值 x,代表他心中预感向这个节点走可能找回自己手机的程度(虽然 他的预感根本不准)。当 Bibi 到达一个节点时,如果该节点有未搜索过的儿子节 点,则 Bibi 会走向未搜索过的儿子节点进行搜索,否则就返回父亲节点。如果 某节点拥有两个未搜索过的儿子节点,Bibi 会选择先搜索权值大的儿子节点。

假设 Bibi 从一个节点到达另一个节点需要 1 单位时间,搜索节点的时间忽 略不计,那么请问当 Bibi 的手机位于编号为 k 的节点时,他需要多少单位时间 才能找到手机。

★数据输入

输入第一行为一个正整数 n(1≤n≤100000)表示树的节点数目,树根的编号 总是为 1。
接下来 n-1 行,每行两个正整数 p,x(1≤x≤100)。代表编号为 i 的节点的父 亲节点 p 和权值 x。这里的 i 从 2 依次数到 n。数据保证输入的 p 小于当前的 i, 且互为兄弟的两个节点的权值 x 不同。
第 n+1 行一个整数 m(1≤m≤n), 表示询问组数。
第 n+2 行有 m 个整数,每个整数 ki(1≤ki≤n)代表该组询问中手机的位置。

★数据输出

输出 m 行,每行一个整数,代表 Bibi 找到手机需要花费的单位时间数量。

输入示例 输出示例
3
1 20
1 30
3
1
2
3
0 3 1

思路

建立一个递归过程来模拟这个搜索过程:

1.用一个变量sum来保存当前走了多少步

2.建立结构体(用父节点表示法建立数组)

struct Tree
{
int value; //保存当前节点的权值
int step; //记录走到该节点的步数
int left; //左儿子编号
int right; //右儿子编号
};

3.递归函数

void search(int i)
{
tree[i].step = sum; //更新该节点的step值
if (tree[i].left == 0 && tree[i].right == 0) //判断该节点是否为叶节点
{
sum++; //返回上一个节点步数+1
return;
}
if (tree[tree[i].left].value>tree[tree[i].right].value) //左儿子权值大于右儿子
{
//tree[i].step += sum++;
sum++; //即将搜索左儿子步数+1
search(tree[i].left); //搜索左儿子
if (tree[tree[i].right].value) //判断是否存在右儿子
{
sum++; //即将搜索右儿子步数+1
search(tree[i].right); //搜索右儿子
}
}
else
{
//tree[i].step += sum++;
sum++;
search(tree[i].right);
if (tree[tree[i].left].value)
{
sum++;
search(tree[i].left);
}
}
sum++; //左右儿子搜索完毕之后返回上个节点步数+1
}

4.递归函数之后每个节点的step值都会被更新,这样我们只要输入节点编号,访问step值就能知道找到这个节点要走多少步了。

Code


#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
struct Tree
{
int value;
int step;
int left;
int right;
};
Tree tree[100001] = { 0 };
int sum = 0;
void search(int i)
{
tree[i].step = sum;
if (tree[i].left == 0 && tree[i].right == 0)
{
sum++;
return;
}
if (tree[tree[i].left].value>tree[tree[i].right].value)
{
//tree[i].step += sum++;
sum++;
search(tree[i].left);
if (tree[tree[i].right].value)
{
sum++;
search(tree[i].right);
}
}
else
{
//tree[i].step += sum++;
sum++;
search(tree[i].right);
if (tree[tree[i].left].value)
{
sum++;
search(tree[i].left);
}
}
sum++;
}
int main()
{
int n;
int m;
int x;
int y;
int i;
int k;
//printf("%d\n", tree[0].value);
scanf("%d", &n);
tree[1].value = 0;
tree[1].step = 0;
for (i = 2; i <= n; i++)
{
scanf("%d %d", &x, &y);
if (!tree[x].left)
{
tree[x].left = i;
tree[i].value = y;
}
else
{
tree[x].right = i;
tree[i].value = y;
}
}
search(1);
scanf("%d", &m);
for (i = 1; i <= m; i++)
{
scanf("%d", &k);
printf("%d", tree[k].step);
if (i<n)printf("\n");
}
return 0;
}

算法与数据结构实验题 6.3 search的更多相关文章

  1. 算法与数据结构实验题 6.4 Summary

    ★实验任务 可怜的 Bibi 丢了好几台手机以后,看谁都像是小偷,他已经在小本本上记 下了他认为的各个地点的小偷数量. 现在我们将 Bibi 的家附近的地形抽象成一棵有根树.每个地点都是树上的 一个节 ...

  2. 算法与数据结构实验题 4.2 小 F 打怪

    ★实验任务 小 F 很爱打怪,今天因为系统 bug,他提前得知了 n 只怪的出现顺序以及击 倒每只怪得到的成就值 ai.设第一只怪出现的时间为第 1 秒,这个游戏每过 1 秒 钟出现一只新怪且没被击倒 ...

  3. 算法与数据结构实验题 4.1 伊姐姐数字 game

    ★实验任务 伊姐姐热衷于各类数字游戏,24 点.2048.数独等轻轻松松毫无压力.一 日,可爱的小姐姐邀请伊姐姐一起玩一种简单的数字 game,游戏规则如下: 一开始桌上放着 n 张数字卡片,从左到右 ...

  4. 算法与数据结构实验题6.4 order (二叉树)

    1.题目: 2.代码: #include<iostream> #include<algorithm> using namespace std; struct Node { in ...

  5. 算法与数据结构实验题 5.2 Missile

    1.题目: 2.解题思路: 把每个点对应的两条半径求出,之后对d1进行升序排序,对应d2也改变位置.其中一个圆心的半径r1确定之后,除去第一个圆包围的点,在其余点中找到另外一个圆的最长的半径r2,此时 ...

  6. 算法与数据结构基础 - 折半查找(Binary Search)

    Binary Search基础 应用于已排序的数据查找其中特定值,是折半查找最常的应用场景.相比线性查找(Linear Search),其时间复杂度减少到O(lgn).算法基本框架如下: //704. ...

  7. 基础算法和数据结构高频题 II

    DFS的两种理解方式:1. 按照实际执行顺序模拟 (适合枚举型DFS,下节课内容)2. 按照DFS的定义宏观理解 (适合分治型DFS,本节课内容) 1 Convert BST to Greater T ...

  8. 第三章 基础算法和数据结构高频题 I

    区间类问题 1 Missing Interval public List<String> findMissingRanges(int[] nums, int lower, int uppe ...

  9. DS实验题 sights

    算法与数据结构实验题 6.3 sights ★实验任务 美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点, 由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱 ...

随机推荐

  1. 从tomcat下载文件的配置方法(很全呢)

    前几天我做的项目有个下载文件的东西让我苦恼了一下,上传的文件没有放到OSS服务器,而是直接放到tomcat内, 我就想做一个a标签直接下载的得了,结果点开一直都说没有该文件,我查了很多资料找到了如何配 ...

  2. IO流,字节流

    /** * IO流,字节流 */ import java.io.FileInputStream; import java.io.FileOutputStream; public class ByStr ...

  3. [转]Javascript removeChild()删除节点及删除子节点的方法(同样适用于jq)

    Javascript removeChild()删除节点及删除子节点的方法 这篇文章主要介绍了Javascript removeChild()删除节点及删除子节点的方法的相关资料,需要的朋友可以参考下 ...

  4. Macbook下安装memcached

    参考文献: https://blog.csdn.net/weixin_41827162/article/details/82049520 感谢大佬 安装memcached需要Homebrew 注意点: ...

  5. 帝国cms教程父栏目和子栏目都能在当前栏目高亮

    首先在/e/class/userfun.php这个文件里面加上下面代码.上面父栏目的,下面子栏目的.红色代表css样式.自定义吧 function currentPage($classid,$this ...

  6. 用turtle库显示汉诺塔问题的过程

    用turtle库显示汉诺塔问题的过程 一.什么是汉诺塔问题? 一座汉诺塔,塔内有3个座A.B.C,A座上有n个盘子,盘子大小不等,大的在下,小的在上,如图所示.把这n个盘子从A座移到C座,但每次只能移 ...

  7. C++的特点

    C和C++ C主要是应用在在驱动层,是面向过程的编程语言,对类型的定义不是很严格.C++主要是应用与应用层,是C语言的一个加强版,可以完全兼容C语言,并且还有很多C语言不具备的特性,如,C++是一种面 ...

  8. Git项目的目录结构

     branch是分支   trunk是主干   bug修正和新功能的添加一般在branch进行 测试好了没问题了就可以合并到trunk 每隔一段时间就可以打包成一个版本放到tags 用于发布的版本一般 ...

  9. 广州Uber优步司机奖励政策(1月11日~1月17日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  10. 武汉Uber优步司机奖励政策

    ·武汉奖励前提 *必须满足当周平均评分4.7星及以上,且当周接单率70%及以上,才有资格获得奖励 *刷单和红线行为立即封号并取消当周全部奖励及车费! *从4月20日起,所有ETC和机场高速费用不参与奖 ...